Firebase实时数据库获取活动中的java.lang.NullPointerException [英] java.lang.NullPointerException in Firebase Realtime Database fetching activity

查看:49
本文介绍了Firebase实时数据库获取活动中的java.lang.NullPointerException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在努力寻找导致错误的原因:java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法'java.lang.String java.lang.Object.toString()'

I have beenn struggling to find out why I am getting the error: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference

以下是错误的完整说明:

Below is the full description of the error:

2021-03-15 14:15:49.906 24447-24447/com.goldencrestit.quicky2 D/Android运行时:关闭VM2021-03-15 14:15:49.907 24447-24447/com.goldencrestit.quicky2 E/AndroidRuntime:FATAL EXCEPTION:main流程:com.goldencrestit.quicky2,PID:24447java.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)

2021-03-15 14:15:49.906 24447-24447/com.goldencrestit.quicky2 D/AndroidRuntime: Shutting down VM 2021-03-15 14:15:49.907 24447-24447/com.goldencrestit.quicky2 E/AndroidRuntime: FATAL EXCEPTION: main Process: com.goldencrestit.quicky2, PID: 24447 java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference at com.goldencrestit.quicky2.ViewProfileActivity$1.onDataChange(ViewProfileActivity.java:64) at com.google.firebase.database.core.ValueEventRegistration.fireEvent(ValueEventRegistration.java:75) at com.google.firebase.database.core.view.DataEvent.fire(DataEvent.java:63) at com.google.firebase.database.core.view.EventRaiser$1.run(EventRaiser.java:55) at android.os.Handler.handleCallback(Handler.java:883) at android.os.Handler.dispatchMessage(Handler.java:100) at android.os.Looper.loop(Looper.java:264) at android.app.ActivityThread.main(ActivityThread.java:7581) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:980)

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

This error pops up when I click on the "View your Profile" button in order to load the profile page.

以下是预期结果.支持从Firebase实时数据库中获取数据以填充虚拟文本:

Below is the expected result. It is support to fetch data from my firebase realtime database to fill the dummy texts:

检查下面的代码:

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);
        }
    }

以下是我要在作业详细信息"布局上显示的内容:

Below is what I am trying to display on the Job Detail Layout:

推荐答案

错误似乎来自这段代码:

The error seems to come from this piece of code:

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()返回 null 然后 toString()会导致您得到异常.

The above code is loading all data from /Company Profile and then trying to read the company_name property from it. But if we look at the data you shared, there is no /Company Profile/company_name property, so that explains why getValue() returns null and the toString() then leads to the exception you get.

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

It seems your JSON tree consists of: /Company Profile/$uid/$pushid. How to property load the data from this structure depends on how much information you already know in your code, so let's look at the options:

如果您同时知道要加载的信息的UID和推送ID ,则可以使用以下方法进行加载:

If you know both the UID and the push ID of the information you want to load, you can do load just that with:

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并使用以下方法对其进行循环:


If you know the UID, but not the push ID, of the information you want to load, you can load all push IDs and loop over them with:

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.这意味着我们可以有多个子节点,因此您可能要考虑使用列表视图/回收器视图来显示数据.

So here we loop over dataSnapshot.getChildren() to get across the unknown push IDs from the database. This means we can have multiple child nodes, so you may want to consider using a list view/recycler view for displaying the data.

最后一种情况是,您不知道要显示的数据的UID或推送ID .在这种情况下,您需要两个嵌套循环来浏览数据,一个循环用于JSON中的UID,另一个用于推送ID.所以:

The final case is if you know neither the UID nor the push ID of the data you want to display. In that case you need two nested loops to navigate over the data, one for the UIDs in the JSON, and one for the push IDs. So:

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元素,因为现在您正在从数据库中导航/解析整个树状结构.

You'll note that the solution is quite similar to the previous one, but now with a second loop. Here too, you'll have to consider what is the best UI element to display the structure, as now you're navigating/parsing an entire tree-like structure from the database.

这篇关于Firebase实时数据库获取活动中的java.lang.NullPointerException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆