Как удалить пользователя Firebase из приложения Android?

Я пытаюсь закодировать метод Delete User в своем приложении для Android, но у меня возникают проблемы при каждом его выполнении. Этот метод будет выполняться, когда пользователь нажимает кнопку "Удалить учетную запись" в разделе "Деятельность". Мои приложения работают с FirebaseUI Auth.

Вот метод:

private void deleteAccount() {
    Log.d(TAG, "ingreso a deleteAccount");
    FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
    final FirebaseUser currentUser = firebaseAuth.getCurrentUser();

    currentUser.delete().addOnCompleteListener(new OnCompleteListener<Void>() {
        @Override
        public void onComplete(@NonNull Task<Void> task) {
            if (task.isSuccessful()) {
                Log.d(TAG,"OK! Works fine!");
                startActivity(new Intent(Main3WelcomeActivity.this, Main3Activity.class));
                finish();
            } 
        }
    }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            Log.e(TAG,"Ocurrio un error durante la eliminación del usuario", e);
        }
    });
}

1) Когда я выполняю эту функцию, на экране появляется сообщение Smart Lock, и пользователь снова входит в систему. Вот скриншот этого сообщения.

Smartlock message

2) В других случаях, когда пользователь вошел в систему в течение длительного времени, функция генерирует исключение, подобное следующему:

06-30 00:01:26.672 11152-11152/com.devpicon.android.firebasesamples E/Main3WelcomeActivity: Ocurrio un error durante la eliminación del usuario
com.google.firebase.FirebaseException: An internal error has occured. [ CREDENTIAL_TOO_OLD_LOGIN_AGAIN ]
at com.google.android.gms.internal.zzacq.zzbN(Unknown Source)
at com.google.android.gms.internal.zzacn$zzg.zza(Unknown Source)
at com.google.android.gms.internal.zzacy.zzbO(Unknown Source)
at com.google.android.gms.internal.zzacy$zza.onFailure(Unknown Source)
at com.google.android.gms.internal.zzact$zza.onTransact(Unknown Source)
at android.os.Binder.execTransact(Binder.java:453)

Я читал, что должен пройти повторную аутентификацию пользователя, но я не уверен, как это сделать, когда я работаю с Google Sign In.

Ответ 1

В соответствии с документацией Firebase пользователь может delete() удалить пользователя из Firebase

Прежде чем удалить пользователя, reAuthenticate пользователь.

Пример кода

     final FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();

        // Get auth credentials from the user for re-authentication. The example below shows
        // email and password credentials but there are multiple possible providers,
        // such as GoogleAuthProvider or FacebookAuthProvider.
        AuthCredential credential = EmailAuthProvider
                .getCredential("[email protected]", "password1234");

        // Prompt the user to re-provide their sign-in credentials
        user.reauthenticate(credential)
                .addOnCompleteListener(new OnCompleteListener<Void>() {
                    @Override
                    public void onComplete(@NonNull Task<Void> task) {
           user.delete()
            .addOnCompleteListener(new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    if (task.isSuccessful()) {
                        Log.d(TAG, "User account deleted.");
                    }
                }
            });

   }
});

Подробнее: https://firebase.google.com/docs/auth/android/manage-users#re-authenticate_a_user

Если вы хотите повторить аутентификацию с другим провайдером singin, нужно изменить Provider для GoogleAuthProvider ниже, это пример кода

GoogleAuthProvider.getCredential(googleIdToken,null);

Ответ 2

Прежде всего, вам нужно сохранить токен аутентификации или пароль в момент входа пользователя. Если ваше приложение не предоставляет таких услуг, как вход в систему Google, вход в Facebook или другие, вам просто нужно для сохранения пароля.

//If there any, delete all stored content from this user on Real Time Database. 
yourDatabaseReferenceNode.removeValue();

//Getting the user instance.
final FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();

if (user != null) {
    //You need to get here the token you saved at logging-in time.
    String token = "userSavedToken";
    //You need to get here the password you saved at logging-in time.
    String password = "userSavedPassword";

    AuthCredential credential;

    //This means you didn't have the token because user used like Facebook Sign-in method.
    if (token == null) {
       credential = EmailAuthProvider.getCredential(user.getEmail(), password);
    } else {
       //Doesn't matter if it was Facebook Sign-in or others. It will always work using GoogleAuthProvider for whatever the provider.
       credential = GoogleAuthProvider.getCredential(token, null);
    }

    //We have to reauthenticate user because we don't know how long 
    //it was the sign-in. Calling reauthenticate, will update the 
    //user login and prevent FirebaseException (CREDENTIAL_TOO_OLD_LOGIN_AGAIN) on user.delete()
    user.reauthenticate(credential)
            .addOnCompleteListener(new OnCompleteListener<Void>() {
                    @Override
                    public void onComplete(@NonNull Task<Void> task) {
                        //Calling delete to remove the user and wait for a result.
                        user.delete().addOnCompleteListener(new OnCompleteListener<Void>() {
                            @Override
                            public void onComplete(@NonNull Task<Void> task) {
                                if (task.isSuccessful()) {
                                    //Ok, user remove
                                } else {
                                    //Handle the exception
                                    task.getException();
                                }
                            }
                        });
                    }
                });    
}        

Ответ 3

Ответ, предоставленный Ансуитой-младшей, очень красиво объяснен и является правильным только с небольшой проблемой. Пользователь удаляется даже без успешной повторной аутентификации. Это потому что мы используем

user.delete()

в методе onComplete(), который всегда выполняется. Поэтому нам нужно добавить проверку if, чтобы проверить, успешно ли выполняется задача, о чем упоминается ниже.

user.reauthenticate(credential)
          .addOnCompleteListener(new OnCompleteListener<Void>() {
             @Override
             public void onComplete(@NonNull Task<Void> task) {
                 if (task.isSuccessful()) {
                    Log.e("TAG", "onComplete: authentication complete");
                    user.delete()
                    .addOnCompleteListener (new OnCompleteListener<Void>() {
                           @Override
                           public void onComplete(@NonNull Task<Void> task) {
                                if (task.isSuccessful()) {
                                    Log.e("TAG", "User account deleted.");
                                } else {
                                    Log.e("TAG", "User account deletion unsucessful.");
                                }
                          }
                     });
                 } else {
                     Toast.makeText(UserProfileActivity.this, "Authentication failed", 
                               Toast.LENGTH_SHORT).show();
                 }
              }
         });

Ответ 4

Обратный вызов delete уже обрабатывает случай сбоя, почему вы добавляете addOnFailureListener позже?

Попробуйте удалить его, следующим образом:

private void deleteAccount() {
    Log.d(TAG, "ingreso a deleteAccount");
    FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
    final FirebaseUser currentUser = firebaseAuth.getCurrentUser();
    currentUser.delete().addOnCompleteListener(new OnCompleteListener<Void>() {
        @Override
        public void onComplete(@NonNull Task<Void> task) {
            if (task.isSuccessful()) {
                Log.d(TAG,"OK! Works fine!");
                startActivity(new Intent(Main3WelcomeActivity.this, Main3Activity.class));
                finish();
            } else {
                Log.w(TAG,"Something is wrong!");
            }
        }
    });
}

Ответ 5

Используйте следующие методы: -

удалить()

эквивалентно вызову set(null).

или

RemoveUser()

removeUser(credentials, [onComplete])

Ответ 6

@Разработчики Android:

Я столкнулся с проблемой, когда информация об Firebase Auth сохранялась на диске устройства ПОСЛЕ удаления приложения. android:allowBackup="false" и прочитав об этом, я обнаружил, что настройка android:allowBackup="false" и android:fullBackupContent="false" в <application> Manifest <application> гарантирует, что идентификационная информация не будет сохранена после удаления приложения.

Обратите внимание, что такого рода постоянство происходило не на всех устройствах Android. Фактически, это начало происходить на одном из моих устройств, у которого никогда не было этой проблемы.

Ответ 7

Только получить текущего пользователя и удалить его, используя следующий метод, он будет работать нормально

user.delete();

и вы можете добавить Oncompletelistner также с помощью addind user.delete().addOnCompleteListner(new OnCompleteListner) и многое другое на