0

My app is getting some errors whenever I click the signout button. I suspect that this causes by the authentication.signout().

This is the error:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.demo.finalssuncrestbank, PID: 17982
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.google.firebase.firestore.DocumentSnapshot.getString(java.lang.String)' on a null object reference
    at com.demo.finalssuncrestbank.UserProfile$1.onEvent(UserProfile.java:52)
    at com.demo.finalssuncrestbank.UserProfile$1.onEvent(UserProfile.java:49)
    at com.google.firebase.firestore.DocumentReference.lambda$addSnapshotListenerInternal$2(DocumentReference.java:483)
    at com.google.firebase.firestore.DocumentReference$$Lambda$3.onEvent(Unknown Source:6)
    at com.google.firebase.firestore.core.AsyncEventListener.lambda$onEvent$0(AsyncEventListener.java:42)
    at com.google.firebase.firestore.core.AsyncEventListener$$Lambda$1.run(Unknown Source:6)
    at android.os.Handler.handleCallback(Handler.java:790)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:169)
    at android.app.ActivityThread.main(ActivityThread.java:6521)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)

The code is this:

DocumentReference documentReference = fStore.collection("Users").document(UserID);
        documentReference.addSnapshotListener(this, new EventListener<DocumentSnapshot>() {
            @Override
            public void onEvent(@Nullable DocumentSnapshot value, @Nullable FirebaseFirestoreException error) {
                mName.setText("Name: " + value.getString("Name"));
                mPhone.setText("Phone: " + value.getString("Phone"));
                mEmail.setText("Email: \n \n" + value.getString("Email"));
                mBalance.setText(String.valueOf(value.getDouble("Balance")));

            }
        });
    LogOut.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            fAuth.signOut();
            Intent intent = new Intent(getApplicationContext(), Login.class);
            startActivity(intent);
        }
    });

I wanted to know what are the possible reasons why this keeps happening and what should I do?

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Jm25E
  • 19
  • 5

2 Answers2

2

You are accessing UI in your listener. The listener will listen to any changes forever or in your user log out listener, you are navigating to another Activity which mean the current Activity/UI is null and the listener addSnapshotListener will be triggred as there is a change in authorisation state.

You must detach your snapshot listener before sending your intent: https://firebase.google.com/docs/firestore/query-data/listen#java_11

DocumentReference documentReference = fStore.collection("Users").document(UserID);
        ListenerRegistration registration = documentReference.addSnapshotListener(this, new EventListener<DocumentSnapshot>() {
            @Override
            public void onEvent(@Nullable DocumentSnapshot value, @Nullable FirebaseFirestoreException error) {
                mName.setText("Name: " + value.getString("Name"));
                mPhone.setText("Phone: " + value.getString("Phone"));
                mEmail.setText("Email: \n \n" + value.getString("Email"));
                mBalance.setText(String.valueOf(value.getDouble("Balance")));

            }
        });
    LogOut.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            // Stop listening to changes
            registration.remove();

            fAuth.signOut();
            Intent intent = new Intent(getApplicationContext(), Login.class);
            startActivity(intent);
        }
    });
khammami
  • 371
  • 4
  • 14
  • so does this mean that it triggers changes i make when going to the next activity, then passing it as null pointer? – Jm25E Feb 12 '21 at 12:54
  • fAuth.signOut(); will trigger Auth state change event that will trigger the snapshot listener right after that startActivity(intent); will stop & destroy the current activity which mean UI will be null, the snapshot is already triggred and is trying to access the textview. – khammami Feb 12 '21 at 13:02
1

When it logout, again it notifies in addSnapshotListener. But this time FirebaseFirestoreException. So make sure before accesing value if there is no error.

 DocumentReference documentReference = fStore.collection("Users").document(UserID);
            documentReference.addSnapshotListener(this, new EventListener<DocumentSnapshot>() {
                @Override
                public void onEvent(@Nullable DocumentSnapshot value, @Nullable FirebaseFirestoreException error) {
                    if( error == null){
                    mName.setText("Name: " + value.getString("Name"));
                    mPhone.setText("Phone: " + value.getString("Phone"));
                    mEmail.setText("Email: \n \n" + value.getString("Email"));
                    mBalance.setText(String.valueOf(value.getDouble("Balance")));
                    }
    
                }
            });
        LogOut.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                fAuth.signOut();
                Intent intent = new Intent(getApplicationContext(), Login.class);
                startActivity(intent);
            }
        });
Kishan Maurya
  • 3,356
  • 8
  • 21