简体   繁体   中英

java.lang.NullPointerException in Firebase Realtime Database fetching activity

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/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.v iew.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.ZC31B32364CE19CA8FCD150A417ECC E58Z.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.

工作门户图片

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

工作细节图像

Check below my codes:

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:

Firebase 上的实时数据库

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

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.

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:


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

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

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.


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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM