【问题标题】:java.lang.NullPointerException in Firebase Realtime Database fetching activityFirebase 实时数据库获取活动中的 java.lang.NullPointerException
【发布时间】:2021-03-16 01:46:17
【问题描述】:

我一直在努力找出我收到错误的原因:java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on an null object reference

以下是错误的完整描述:

2021-03-15 14:15:49.906 24447-24447/com.goldencrestit.quicky2 D/AndroidRuntime:关闭 VM 2021-03-15 14:15:49.907 24447-24447/com.goldencrestit.quicky2 E/AndroidRuntime: 致命异常: main 进程:com.goldencrestit.quicky2,PID:24447 java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“java.lang.String java.lang.Object.toString()” 在 com.goldencrestit.quicky2.ViewProfileActivity$1.onDataChange(ViewProfileActivity.java:64) 在 com.google.firebase.database.core.ValueEventRegistration.fireEvent(ValueEventRegistration.java:75) 在 com.google.firebase.database.core.view.DataEvent.fire(DataEvent.java:63) 在 com.google.firebase.database.core.view.EventRaiser$1.run(EventRaiser.java:55) 在 android.os.Handler.handleCallback(Handler.java:883) 在 android.os.Handler.dispatchMessage(Handler.java:100) 在 android.os.Looper.loop(Looper.java:264) 在 android.app.ActivityThread.main(ActivityThread.java:7581) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:980)

当我单击“查看您的个人资料”按钮以加载个人资料页面时会弹出此错误。

以下是预期结果。支持从我的 firebase 实时数据库中获取数据来填充虚拟文本:

检查下面我的代码:

activity_company_portal.xml


    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/bg_color"
        android:orientation="vertical"
        tools:context=".CompanyPortal">
    
        <include
            layout="@layout/toolbar"
            android:id="@+id/toolbar_home" />
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="right"
            android:padding="20dp"
            android:orientation="horizontal">
    
            <ImageButton
                android:id="@+id/logout_btn"
                android:layout_width="50dp"
                android:layout_height="50dp"
                android:background="@drawable/ic_baseline_power_settings_new_24" />
    
        </LinearLayout>
    
        <ImageView
            android:id="@+id/imageView3"
            android:layout_width="100dp"
            android:layout_height="100dp"
            android:layout_gravity="center"
            android:layout_marginTop="10dp"
            app:srcCompat="@drawable/logo" />
    
    
        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:padding="20dp">
    
            <Button
                android:id="@+id/view_job"
                android:layout_width="match_parent"
                android:layout_height="60dp"
                android:background="@drawable/button_bg"
                android:layout_marginTop="20dp"
                android:textColor="@color/text_color_secondary"
                android:textSize="16sp"
                android:letterSpacing=".2"
                android:text="@string/view_all_jobs" />
    
            <Button
                android:id="@+id/add_job"
                android:layout_width="match_parent"
                android:layout_height="60dp"
                android:background="@drawable/button_bg"
                android:layout_marginTop="50dp"
                android:textColor="@color/text_color_secondary"
                android:layout_below="@id/view_job"
                android:textSize="16sp"
                android:letterSpacing=".2"
                android:text="@string/add_a_new_job" />
    
            <Button
                android:id="@+id/edit_profile"
                android:layout_width="match_parent"
                android:layout_height="60dp"
                android:background="@drawable/button_bg"
                android:layout_marginTop="50dp"
                android:textColor="@color/text_color_secondary"
                android:layout_below="@id/add_job"
                android:textSize="16sp"
                android:letterSpacing=".2"
                android:text="@string/edit_your_profile" />
    
            <Button
                android:id="@+id/view_profile"
                android:layout_width="match_parent"
                android:layout_height="60dp"
                android:background="@drawable/button_bg"
                android:layout_marginTop="50dp"
                android:textColor="@color/text_color_secondary"
                android:layout_below="@id/edit_profile"
                android:textSize="16sp"
                android:letterSpacing=".2"
                android:text="@string/view_your_profile" />
        </RelativeLayout>
    </LinearLayout>

CompanyPortalActivity.java


    public class CompanyPortalActivity extends AppCompatActivity {
    
        private FirebaseAuth mAuth;
        private FirebaseUser mCurrentUser;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_company_portal);
    
            Toolbar toolbar = findViewById(R.id.toolbar_home);
            setSupportActionBar(toolbar);
            Objects.requireNonNull(getSupportActionBar()).setTitle("Quicky Job Portal");
    
            Button viewJobs = findViewById(R.id.view_job);
            Button postJobs = findViewById(R.id.add_job);
            Button edit_profile = findViewById(R.id.edit_profile);
            Button view_profile = findViewById(R.id.view_profile);
    
    
            viewJobs.setOnClickListener(v -> startActivity(new Intent(getApplicationContext(), IndividualPostActivity.class)));
    
            postJobs.setOnClickListener(v -> startActivity(new Intent(getApplicationContext(), PostJobsActivity.class)));
    
            edit_profile.setOnClickListener(v -> startActivity(new Intent(getApplicationContext(), EditProfileActivity.class)));
    
            view_profile.setOnClickListener(v -> startActivity(new Intent(getApplicationContext(), ViewProfileActivity.class)));
    
            mAuth = FirebaseAuth.getInstance();
            mCurrentUser = mAuth.getCurrentUser();
    
            ImageButton mLogoutBtn = findViewById(R.id.logout_btn);
    
            mLogoutBtn.setOnClickListener(v -> {
    
                mAuth.signOut();
                sendUserToLogin();
    
            });
        }
        @Override
        protected void onStart() {
            super.onStart();
            if(mCurrentUser == null){
                sendUserToLogin();
            }
        }
    
        private void sendUserToLogin() {
            Intent loginIntent = new Intent(getApplicationContext(), CompanyLoginActivity.class);
            loginIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            loginIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
            startActivity(loginIntent);
            finish();
        }
    }

activity_view_profile.xml


    <?xml version="1.0" encoding="utf-8"?>
    <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/bg_color"
        tools:context=".ViewProfileActivity">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">
    
            <include
                layout="@layout/toolbar"
                android:id="@+id/toolbar"/>
    
            <ImageView
                android:id="@+id/imageView7"
                android:layout_width="match_parent"
                android:layout_height="50dp"
                app:srcCompat="@drawable/logo" />
    
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColor="@color/text_color_primary"
                android:layout_marginTop="10dp"
                android:layout_marginEnd="40dp"
                android:layout_marginStart="40dp"
                android:text="Company Name" />
    
            <TextView
                android:id="@+id/company_name"
                android:layout_width="match_parent"
                android:layout_height="40dp"
                android:layout_marginTop="5dp"
                android:layout_marginEnd="40dp"
                android:layout_marginBottom="20dp"
                android:textAlignment="center"
                android:layout_marginStart="40dp"
                android:textColor="@color/text_color_secondary"
                android:text="Golden Crest Tech"
                android:background="@drawable/text_display" />
    
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColor="@color/text_color_primary"
                android:layout_marginEnd="40dp"
                android:layout_marginStart="40dp"
                android:text="Business Type" />
    
            <TextView
                android:id="@+id/business_type"
                android:layout_width="match_parent"
                android:layout_height="40dp"
                android:layout_marginTop="5dp"
                android:layout_marginEnd="40dp"
                android:layout_marginBottom="20dp"
                android:textAlignment="center"
                android:layout_marginStart="40dp"
                android:textColor="@color/text_color_secondary"
                android:text="Technology"
                android:background="@drawable/text_display" />
    
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColor="@color/text_color_primary"
                android:layout_marginEnd="40dp"
                android:layout_marginStart="40dp"
                android:text="Phone Number" />
    
            <TextView
                android:id="@+id/phone_number"
                android:layout_width="match_parent"
                android:layout_height="40dp"
                android:layout_marginTop="5dp"
                android:layout_marginEnd="40dp"
                android:layout_marginBottom="20dp"
                android:textAlignment="center"
                android:layout_marginStart="40dp"
                android:textColor="@color/text_color_secondary"
                android:text="08020345678"
                android:background="@drawable/text_display" />
    
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColor="@color/text_color_primary"
                android:layout_marginEnd="40dp"
                android:layout_marginStart="40dp"
                android:text="Company Address" />
    
            <TextView
                android:id="@+id/address"
                android:layout_width="match_parent"
                android:layout_height="40dp"
                android:layout_marginTop="5dp"
                android:layout_marginEnd="40dp"
                android:layout_marginBottom="20dp"
                android:textAlignment="center"
                android:layout_marginStart="40dp"
                android:textColor="@color/text_color_secondary"
                android:text="Surulere, Lagos"
                android:background="@drawable/text_display" />
    
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColor="@color/text_color_primary"
                android:layout_marginEnd="40dp"
                android:layout_marginStart="40dp"
                android:layout_marginBottom="5dp"
                android:text="Company Detail" />
    
            <EditText
                android:id="@+id/editTextTextMultiLine"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginStart="40dp"
                android:layout_marginEnd="40dp"
                android:background="@drawable/text_display_2"
                android:clickable="false"
                android:editable="false"
                android:ems="10"
                android:enabled="false"
                android:fontFamily="@font/open_sans"
                android:gravity="start|top"
                android:inputType="textMultiLine"
                android:text="@string/company_detail_dummy"
                android:textColor="@color/text_color_secondary"
                android:textSize="14sp" />
    
            <Button
                android:id="@+id/edit_profile"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@drawable/button_bg"
                android:layout_marginLeft="40dp"
                android:layout_marginRight="40dp"
                android:layout_marginTop="10dp"
                android:layout_marginBottom="20dp"
                android:textColor="@color/text_color_secondary"
                android:textAllCaps="false"
                android:textSize="16sp"
                android:text="Edit Profile" />
    
    
        </LinearLayout>
    </ScrollView>

ViewProfileActivity.java


    public class ViewProfileActivity extends AppCompatActivity {
    
        private DatabaseReference myRef;
    
        TextView company_name_txt, business_type_txt, phone_number_txt, company_address_txt;
        EditText company_detail_txt;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_view_profile);
    
            company_name_txt = findViewById(R.id.company_name);
            business_type_txt = findViewById(R.id.business_type);
            phone_number_txt = findViewById(R.id.phone_number);
            company_address_txt = findViewById(R.id.address);
            company_detail_txt = findViewById(R.id.company_detail);
    
            Toolbar toolbar = findViewById(R.id.toolbar);
            setSupportActionBar(toolbar);
            Objects.requireNonNull(getSupportActionBar()).setTitle("Company Profile");
            Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true);
            Objects.requireNonNull(getSupportActionBar()).setDisplayShowHomeEnabled(true);
    
            myRef = FirebaseDatabase.getInstance().getReference().child("Company Profile");
            myRef.addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot snapshot) {
                    if (snapshot.exists()){
                        String companyName = snapshot.child("company_name").getValue().toString();
                        String phoneNumber = snapshot.child("phone_number").getValue().toString();
                        String companyAddress= snapshot.child("address").getValue().toString();
                        String businessType = snapshot.child("business_type").getValue().toString();
    
                        company_name_txt.setText(companyName);
                        business_type_txt.setText(businessType);
                        company_address_txt.setText(companyAddress);
                        phone_number_txt.setText(phoneNumber);
                    }
                }
    
                @Override
                public void onCancelled(@NonNull DatabaseError error) {}
            });
        }
    
        @Override
        public boolean onOptionsItemSelected(@NonNull MenuItem item) {
            if (item.getItemId()==android.R.id.home){
                finish();
            }
            return super.onOptionsItemSelected(item);
        }
    }

下面是我试图在作业详细布局上显示的内容:

【问题讨论】:

    标签: java android xml firebase firebase-realtime-database


    【解决方案1】:

    错误似乎来自这段代码:

    myRef = FirebaseDatabase.getInstance().getReference().child("Company Profile");
    myRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            if (snapshot.exists()){
                String companyName = snapshot.child("company_name").getValue().toString();
                String phoneNumber = snapshot.child("phone_number").getValue().toString();
                String companyAddress= snapshot.child("address").getValue().toString();
                String businessType = snapshot.child("business_type").getValue().toString();
    
                company_name_txt.setText(companyName);
                business_type_txt.setText(businessType);
                company_address_txt.setText(companyAddress);
                phone_number_txt.setText(phoneNumber);
            }
        }
    
        @Override
        public void onCancelled(@NonNull DatabaseError error) {}
    });
    

    上面的代码正在从/Company Profile 加载所有数据,然后尝试从中读取company_name 属性。但是,如果我们查看您共享的数据,则没有 /Company Profile/company_name 属性,这就解释了为什么 getValue() 返回 nulltoString() 会导致您得到异常。

    您的 JSON 树似乎包含:/Company Profile/$uid/$pushid。如何从这个结构中属性加载数据取决于你在代码中已经知道多少信息,所以让我们看看选项:


    如果您知道要加载的信息的 UID 和推送 ID,则可以通过以下方式加载:

    myRef = FirebaseDatabase.getInstance().getReference().child("Company Profile");
    String uid = "6babpG...MxLg33"; // must be the exact, complete value
    String pushid = "-MVmyqx...3rwsAO"; // must be the exact, complete value
    myRef.child(uid).child(pushid().addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            if (snapshot.exists()){
                String companyName = snapshot.child("company_name").getValue().toString();
                ...
            }
        }
    
        @Override
        public void onCancelled(@NonNull DatabaseError error) {
            throw error.toException(); // never ignore errors
        }
    });
    

    如果您知道要加载的信息的 UID,但不知道推送 ID,您可以加载所有推送 ID 并循环使用:

    myRef = FirebaseDatabase.getInstance().getReference().child("Company Profile");
    String uid = "6babpG...MxLg33"; // must be the exact, complete value
    myRef.child(uid).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            for (DataSnapshot snapshot: dataSnapshot.getChildren()) {
                String companyName = snapshot.child("company_name").getValue().toString();
                ...
            }
        }
    
        @Override
        public void onCancelled(@NonNull DatabaseError error) {
            throw error.toException(); // never ignore errors
        }
    });
    

    所以我们在这里循环dataSnapshot.getChildren() 以从数据库中获取未知的推送 ID。这意味着我们可以有多个子节点,因此您可能需要考虑使用列表视图/回收器视图来显示数据。


    最后一种情况是,如果您既不知道要显示的数据的 UID 也不知道推送 ID。在这种情况下,您需要两个嵌套循环来导航数据,一个用于 JSON 中的 UID,另一个用于推送 ID。所以:

    myRef = FirebaseDatabase.getInstance().getReference().child("Company Profile");
    myRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            for (DataSnapshot userSnapshot: dataSnapshot.getChildren()) {
                for (DataSnapshot snapshot: userSnapshot.getChildren()) {
                    String companyName = snapshot.child("company_name").getValue().toString();
                    ...
                }
            }
        }
    
        @Override
        public void onCancelled(@NonNull DatabaseError error) {
            throw error.toException(); // never ignore errors
        }
    });
    

    您会注意到该解决方案与前一个解决方案非常相似,但现在有了第二个循环。在这里,您也必须考虑显示结构的最佳 UI 元素是什么,因为现在您正在从数据库中导航/解析整个树状结构。

    【讨论】:

    • 这对我有用,我可以使用 getUid() 函数获取 uId,但无法获取推送 ID。是否有功能可以让我获得一个特定的推送 ID,这样我就不必按原样从数据库中复制它。我只是想假设我无权访问数据库。
    • 我不确定你的意思。当您调用 push() 然后将数据写入该新位置时,会生成一个推送 ID。如果您也需要在其他地方推送,则应在第一次生成时将其存储在那里。如果您的数据结构中不需要推送 ID,则不应在代码中调用 push()
    • 我把push()函数去掉了,解决了。
    猜你喜欢
    • 2019-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-30
    相关资源
    最近更新 更多