-1

I have 2 different fragments: one with an EventListener that checks for changes in Firebase, this is the code:

dbUsers.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            User user = dataSnapshot.getValue(User.class);
            favo_team_view = (TextView) myView.findViewById(R.id.favo_team_textview);

            if(!(user.getTeam() == null)) {
                favo_team_view.setText("Your favourite team is: " + user.getTeam());
            } else {
                favo_team_view.setText("Your favourite team is: " );
            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });

And another fragment that deletes an entry in the database, and starts an intent to start the SignInActivity (Both fragments are part of the MainActivity) ; this is the code

Button deleteUserButton = myView.findViewById(R.id.delete_user);
    deleteUserButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            final String uid = auth.getUid();
            final DatabaseReference dbUsers = FirebaseDatabase.getInstance().getReference("users").child(uid);
            auth.getCurrentUser().delete().addOnCompleteListener(new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    if(task.isSuccessful()){
                        dbUsers.setValue(null);
                        signOut();

                    }else{
                        displayMessage(getString(R.string.user_deletion_error));
                    }
                }
            });
        }
    });

private void signOut(){
    Intent signOutIntent = new Intent(myView.getContext(), SigninActivity.class);
    startActivity(signOutIntent);
    //finish();
}

The code works in that the entry in the DB gets deleted. But my app crashes, and the stacktrace tells me:

Java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.User.getTeam()' on a null object reference at com.ChooseTeam$1.onDataChange

Why does it do that? I don't understand why the Listener still checks for data-changes (that fragment is not active/open when I delete the database)

Thank you

PS: realized i can't check a string on == null, just thought I'd give it a shot. Same thing without the if statement ofcourse

user3302053
  • 81
  • 2
  • 8

2 Answers2

1

You should check if Datasnapshot exists at first like,

 if(datasnapshop.exists(){
    //Your codes here
 }

You cannot put "==" for comparing Strings in Java, have you tried

if(user.getTeam().equals(null) //statement ;

And have you unregistered the listener when Fragment pauses (in OnPause event)?

SafalFrom2050
  • 687
  • 6
  • 12
  • I checked if auth.getCurrentUser() is null, and that works for me now. But the listener is in the oncreateview, if I remove it in onPause, I would also have to reattach in onResume ? – user3302053 Jun 04 '18 at 11:17
  • 1
    @user3302053 See **[here](https://stackoverflow.com/questions/48861350/should-i-actually-remove-the-valueeventlistener/48862873)** how you can attach and deattach the listener. – Alex Mamo Jun 04 '18 at 12:21
  • 1
    @user3302053 you definitely need to reattach it again if you are planning to use it :) – SafalFrom2050 Jun 04 '18 at 12:24
1

When you add a listener with dbUsers.addValueEventListener that listener:

  1. Calls your onDataChanged with the latest (or cached) value for the node right away.
  2. Starts listening for updates to that node on the server, and calls your onDataChanged again when there are changes.

It will continue listening until you remove the listener with dbUsers.removeEventListener(...).

There are two possible use-cases, each with their own solution.

  1. You only need the data once. In this case, simply change your call addValueEventListener to addListenerForSingleValueEvent, which will automatically unregister the listener after the first call to your onDataChange.
  2. You need the data to stay up to date, but only while your activity is active. In that case: 2.1. Keep a reference to your listener when you register it. I.e. ValueEventListener mUsersListener and mUsersListener = new ValueEventListener(.... 2.2. Remove the listener in onStop, onPause, or another relevant lifecycle method with dbUsers.removeEventListener(mUsersListener)
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807