如何从Android应用中删除Firebase用户?

26
我正在尝试在我的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) 当我执行该函数时,屏幕上会出现智能锁定消息,并且用户会再次登录。这是该消息的截图。

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登录时,不确定如何执行此操作。


使用 removeUser({credentials}) 将其删除。 - Maheshwar Ligade
10个回答

32
根据Firebase文档,用户可以使用delete()方法从Firebase中删除用户。在删除用户之前,请重新验证该用户。
引用代码
```HTML

根据Firebase文档,用户可以使用delete()方法从Firebase中删除用户。在删除用户之前,请重新验证该用户。

示例代码

```
     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("user@example.com", "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

如果您想使用其他登录提供程序进行重新认证,只需更改下面GoogleAuthProvider中的Provider即可。以下是示例代码:

GoogleAuthProvider.getCredential(googleIdToken,null);

2
你必须按照相同的步骤进行操作:AuthCredential credential = GoogleAuthProvider.getCredential(googleIdToken,null); 其他所有步骤都相同。 - Maheshwar Ligade
1
https://firebase.google.com/docs/auth/web/manage-users 这个链接可能会有用。 - Maheshwar Ligade
谢谢您。但我还想问您一个问题。您展示给我们的这段代码,可以删除 Facebook 用户吗? - Yunus Haznedar
1
这将从Firebase数据库中删除用户,如果Firebase中存在Facebook用户身份验证数据,则可能会被删除。虽然我没有尝试过,但如果我们考虑一般行为,这可能会被删除。 - Maheshwar Ligade
好的,这很奇怪,我怎么能知道用户的密码呢? - Yunus Haznedar
显示剩余5条评论

6
Ansuita Jr.提供的答案解释得非常清楚,而且正确,只有一个小问题。 即使没有成功重新验证,用户也会被删除。 这是因为我们在onComplete()方法中使用了user.delete(),该方法始终执行。 因此,我们需要添加一个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();
                 }
              }
         });

3

您的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!");
            }
        }
    });
}

3

首先,在用户登录时,您需要存储认证令牌或密码。如果您的应用程序没有提供Google登录、Facebook登录或其他登录方式,您只需要存储密码。

//If there's 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();
                                }
                            }
                        });
                    }
                });    
}        

先生,我想删除当前已经认证的用户。我的意思是应用程序中的用户已登录并决定删除其帐户。我该怎么做? - Yunus Haznedar
多提供者身份验证的答案和评论解释非常好。 - Jantzilla
@Vansuita Jr. 这个可以工作,但是当我重新验证时,它也可以使用无效密码工作,这不应该是这种情况。 - MARSH

1

@Android 开发者:

我遇到了一个问题,即 Firebase Auth 信息在卸载应用后仍然存在于设备的磁盘中。经过实验和阅读相关资料,我发现在清单文件的 <application> 标签中设置 android:allowBackup="false"android:fullBackupContent="false" 可以确保身份信息在应用卸载后不会被持久化。

请注意,这种持久化并不会发生在所有 Android 设备上。事实上,它开始在我的一台从未出现此问题的设备上发生。


1
如果登录方式是“匿名”,您只需调用
FirebaseAuth.getInstance().getCurrentUser().delete().addOnCompleteListener(task -> {
                       if (task.isSuccessful()){
                           Log.d(TAG, "Deletion Success");
                       }
                    });

但如果使用不同的方法,您将需要重新验证身份。如何重新验证身份


0

只需使用以下方法获取当前用户并将其删除,它就可以正常工作

user.delete();

你还可以添加OnCompleteListener,方法是通过添加user.delete().addOnCompleteListener(new OnCompleteListener)等等


0

使用以下方法:

remove()

相当于调用 set(null)

或者

removeUser()

removeUser(credentials, [onComplete])

0
如果您正在使用FirebaseUI Auth,您只需执行以下操作即可:
private void delete() {
    FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
    FirebaseUser user=firebaseAuth.getCurrentUser();
    user.delete()
            .addOnCompleteListener(new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    if (task.isSuccessful()){
                        startActivity(new Intent(Main3WelcomeActivity.this, Main3Activity.class));
                        finish();
                        Toast.makeText(Main3WelcomeActivity.this,"Account deleted",Toast.LENGTH_LONG).show();
                    }else {
                        Toast.makeText(Home.this,"failed",Toast.LENGTH_LONG).show();

                    }

                }
            });}

您的回答可以通过添加更多支持信息来改进。请[编辑]以添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案正确。您可以在帮助中心中找到有关如何撰写好答案的更多信息。 - Community

0
如果您正在使用 AuthUIFirebaseAuth,您只需执行以下操作即可:
 AuthUI.getInstance().delete(context).addOnSuccessListener {
           
 }.addOnFailureListener{

 }

或者

FirebaseAuth.getInstance().currentUser.delete().addOnSuccessListener...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接