0

My main goal is to delete an account on both Firebase Auth and Firebase Database. I'm using an interface to synchronize the reception of data, a button to delete and a function to return my User.

Initial variables:

FirebaseAuth mAuth = FirebaseAuth.getInstance();
final FirebaseUser mUser = mAuth.getCurrentUser();
DatabaseReference mUserRef = FirebaseDatabase.getInstance().getReference("Users");

The interface:

public interface IMyInterface {
     void returnUser(User user);
}

The button to delete User:

btnDeleteAccount.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        readUser(new IMyInterface() {
            @Override
            public void returnUser(User user) {
                String email = user.getEmail();
                String password = user.getPassword();
                Log.d("EMAIL+PASSWORD", email+password);
                AuthCredential credential = EmailAuthProvider
                    .getCredential(user.getEmail(), user.getPassword());
                mUser.reauthenticate(credential).addOnCompleteListener(new OnCompleteListener<Void>() {
                    @Override
                    public void onComplete(@NonNull Task<Void> task) {
                        if(task.isSuccessful()) {
                            mUser.delete().addOnCompleteListener(new OnCompleteListener<Void>() {
                                @Override
                                public void onComplete(@NonNull Task<Void> task) {
                                if (task.isSuccessful()) {
                                    mUserRef.child(mUser.getUid()).removeValue();
                                    mAuth.signOut();
                                    finish();
                                    startActivity(new Intent(MainActivity.this, LoginActivity.class));
                                    Toast.makeText(MainActivity.this, "User account deleted!", Toast.LENGTH_SHORT).show();
                                    }
                                }
                            });
                        }
                    }
                });
            }
        });
    }
});

And the function to retrieve a User with user informations:

private void readUser(final IMyInterface myCallback) {
    mUserRef.child(mUser.getUid()).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            user = dataSnapshot.getValue(User.class);
            myCallback.returnUser(user);
        }

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

So, after calling the button, it calls the function to receive the user informations (email and password) and then it uses both information to delete and log out. The problem is that when the last command inside the button ends, it restarts the button at String email = user.getEmail(), but since it does not have an User instantiated, the getEmail() method returns null and the app crashes.

Why is it returning again the method? Or is there something about synchronization which I'm missing? I do have another button which ends when User info is used and it needs to change activity.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
E.Akio
  • 2,249
  • 3
  • 14
  • 27

1 Answers1

1

You have this behaviour because you are using addValueEventListener method instead of addListenerForSingleValueEvent. Mosty, both do the same thing but there is a difference, addListenerForSingleValueEvent disconnects straight after getting the data, while addValueEventListener keeps listening.

So to sovle this, use the addListenerForSingleValueEvent method or remove the listener according to the life-cycle of your activity.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • Yes! I saw this right when you posted! I was receiving a new data and the 'addValueEventListener' was being called. Thank you man – E.Akio Dec 21 '18 at 13:43