java - 尝试使用 Google 登录凭据在 Firebase 上重新进行身份验证时出错

标签 java android firebase firebase-authentication google-signin

<小时/>

tl;博士

(ID Token issued at 1589401401 is stale to sign-in.)

<小时/>

问题:

我的应用使用 Google Sign-in with Firebase。 用户登录后,他可以选择删除他的帐户,这也会从 firebase 身份验证中删除他的用户。 登录工作完全正常。从 Firebase 中删除用户也可以按预期工作。

仅当用户在尝试删除帐户前一小时左右登录时才会发生此错误。

ERROR deleting user: task fail 
com.google.firebase.auth.FirebaseAuthInvalidCredentialsException:
The supplied auth credential is malformed or has expired.
[ ID Token issued at 1589401401 is stale to sign-in. ]

更多详细信息:

Firebase 要求在帐户删除等敏感操作之前进行最近的身份验证,因此我正在使用 “user.reauthenticate(credential)”在“user.delete()”之前

删除用户代码流:

user.delete() -> 如果错误:FirebaseAuthRecentLoginRequiredException -> user.reauthenticate(credential) -> user.delete()

奇怪的是,如果距离上次登录仅过去了大约 30 分钟,重新身份验证实际上会成功,但如果大约一个小时或更长时间,则会失败。 另外,它之前工作得很好,但我无法知道发生了什么变化,现在我收到了这个错误

我假设我可以强制用户使用谷歌登录再次登录,但据我所知 对于谷歌登录方法来说,这不是强制性的,因为我使用以下方式获取用户 ID token : GoogleSignIn.getLastSignedInAccount() 并将 token ID 作为凭据传递给 reauthenticate()

我的代码:

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

    private void userDelete() {
        Log.d(TAG, "userDelete: Deleting user...");
        user.delete().addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void aVoid) {
                Log.d(TAG, "onSuccess: User deleted");
                Log.d(TAG, "userDelete: Signing out...");
                signOut(); //Signing out from Firebase and Google log-in
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Log.d(TAG, "onFailure: Error deleteing user, probebly need to reauthenticate");
                Log.e(TAG, "onFailure: Error:", e);
                reAuthenticateUser(); //reauth and delete user
            }
        });


    }

如果出现用户删除错误,请重新验证用户:

    private void reAuthenticateUser() {
        Log.d(TAG, "reAuthenticateUser: Reauthenticating");
        final FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
// Get the account
        GoogleSignInAccount signInAccount = GoogleSignIn.getLastSignedInAccount(getContext());
        if (signInAccount != null) {
            AuthCredential credential = GoogleAuthProvider.getCredential(signInAccount.getIdToken(), null);
            user.reauthenticate(credential).addOnCompleteListener(new OnCompleteListener<Void>() {
                @Override
                public void onComplete(@NonNull Task<Void> task) {
                    if (task.isSuccessful()) {
                        Log.d(TAG, "Reauthenticated.");
                        Log.d(TAG, "onComplete: Try to delete user again...");
                        user.delete().addOnSuccessListener(new OnSuccessListener<Void>() {
                            @Override
                            public void onSuccess(Void aVoid) {
                                Log.d(TAG, "onSuccess: user deleted successfully");
                                Log.d(TAG, "onComplete: signing out...");
                                signOut();
                            }
                        });
                    } else {
                        Log.e(TAG, "onComplete: ERROR deleting user: task fail", task.getException());
                    }
                }
            });
        } else {
            Log.d(TAG, "Error: reAuthenticateUser: user account is null");
        }

    }

删除用户后注销:

private void signOut() {
        //sign out from firebase
        FirebaseAuth.getInstance().signOut();
        //sign out from "google sign in"
        googleSignInClient.signOut().addOnCompleteListener(new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                //Get back to login screen
                Intent intent = new Intent(getContext(), LoginActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(intent);
                getActivity().finish();
            }
        });
    }

错误:

D/Settings fragment:: onFailure: Error deleteing user, probebly need to reauthenticate E/Settings fragment:: onFailure: Error:
    com.google.firebase.auth.FirebaseAuthRecentLoginRequiredException: This operation is sensitive and requires recent authentication. Log in again before retrying this request.
        at com.google.firebase.auth.api.internal.zzdx.zza(com.google.firebase:firebase-auth@@19.1.0:4)
        at com.google.firebase.auth.api.internal.zzfa.zza(com.google.firebase:firebase-auth@@19.1.0:21)
        at com.google.firebase.auth.api.internal.zzet.zza(com.google.firebase:firebase-auth@@19.1.0:34)
        at com.google.firebase.auth.api.internal.zzev.zza(com.google.firebase:firebase-auth@@19.1.0:74)
        at com.google.firebase.auth.api.internal.zzed.zza(com.google.firebase:firebase-auth@@19.1.0:18)
        at com.google.android.gms.internal.firebase_auth.zza.onTransact(com.google.firebase:firebase-auth@@19.1.0:13)
        at android.os.Binder.execTransactInternal(Binder.java:1021)
        at android.os.Binder.execTransact(Binder.java:994) D/Settings fragment:: reAuthenticateUser: Reauthenticating I/BiChannelGoogleApi: [FirebaseAuth: ] getGoogleApiForMethod() returned Gms: com.google.firebase.auth.api.internal.zzao@da6aa2a E/Settings fragment:: onComplete: ERROR deleting user: task fail
    com.google.firebase.auth.FirebaseAuthInvalidCredentialsException: The supplied auth credential is malformed or has expired. [ ID Token issued at 1589401401 is stale to sign-in. ]
        at com.google.firebase.auth.api.internal.zzdx.zza(com.google.firebase:firebase-auth@@19.1.0:30)
        at com.google.firebase.auth.api.internal.zzfa.zza(com.google.firebase:firebase-auth@@19.1.0:21)
        at com.google.firebase.auth.api.internal.zzet.zza(com.google.firebase:firebase-auth@@19.1.0:34)
        at com.google.firebase.auth.api.internal.zzev.zza(com.google.firebase:firebase-auth@@19.1.0:74)
        at com.google.firebase.auth.api.internal.zzed.zza(com.google.firebase:firebase-auth@@19.1.0:18)
        at com.google.android.gms.internal.firebase_auth.zza.onTransact(com.google.firebase:firebase-auth@@19.1.0:13)
        at android.os.Binder.execTransactInternal(Binder.java:1021)
        at android.os.Binder.execTransact(Binder.java:994)

另外,如果在上次登录后大约 15-30 分钟后尝试删除用户,则会出现(已处理)错误。 在这种情况下,重新身份验证将按预期工作。

D/Settings fragment:: userDelete: Deleting user... I/BiChannelGoogleApi: [FirebaseAuth: ] getGoogleApiForMethod() returned Gms: com.google.firebase.auth.api.internal.zzaq@c066c75 D/Settings fragment:: onFailure: Error deleteing user, probebly need to reauthenticate E/Settings fragment:: onFailure: Error:
    com.google.firebase.auth.FirebaseAuthRecentLoginRequiredException: This operation is sensitive and requires recent authentication. Log in again before retrying this request.
        at com.google.firebase.auth.api.internal.zzeh.zza(com.google.firebase:firebase-auth@@19.3.1:4)
        at com.google.firebase.auth.api.internal.zzfo.zza(com.google.firebase:firebase-auth@@19.3.1:21)
        at com.google.firebase.auth.api.internal.zzfe.zza(com.google.firebase:firebase-auth@@19.3.1:33)
        at com.google.firebase.auth.api.internal.zzfg.zza(com.google.firebase:firebase-auth@@19.3.1:74)
        at com.google.firebase.auth.api.internal.zzen.zza(com.google.firebase:firebase-auth@@19.3.1:18)
        at com.google.android.gms.internal.firebase_auth.zza.onTransact(com.google.firebase:firebase-auth@@19.3.1:13)
        at android.os.Binder.execTransactInternal(Binder.java:1021)
        at android.os.Binder.execTransact(Binder.java:994) D/Settings fragment:: reAuthenticateUser: Reauthenticating I/BiChannelGoogleApi: [FirebaseAuth: ] getGoogleApiForMethod() returned Gms: com.google.firebase.auth.api.internal.zzaq@c066c75 D/FirebaseAuth: Notifying id token listeners about user ( OF22mQlCILNAirW9tN87SV8WAiY2 ). D/Settings fragment:: Reauthenticated. D/Settings fragment:: onComplete: Try to delete user again... I/BiChannelGoogleApi: [FirebaseAuth: ] getGoogleApiForMethod() returned Gms: com.google.firebase.auth.api.internal.zzaq@c066c75 D/FirebaseAuth: Notifying id token listeners about a sign-out event.
    Notifying auth state listeners about a sign-out event. D/Settings fragment:: onSuccess: user deleted successfully

谢谢

最佳答案

所以我最终要求用户再次登录。

除了强制用户通过再次登录来获取刷新的 token 之外,没有找到任何解决方案。 正如 Firebase 文档所示: "Firebase ID tokens are short lived and last for an hour" .

在执行删除用户等危险操作时,会调用 Firebase 身份验证。 在这种情况下,“静默登录”也是不可能的。

我认为删除 Firebase 用户的最佳做法是首先尝试重新身份验证(如果重新身份验证失败,您无论如何都无法删除该用户) 如果失败,则要求用户重新登录或按顺序启动登录。

关于java - 尝试使用 Google 登录凭据在 Firebase 上重新进行身份验证时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61797048/

相关文章:

java - 在运行时更改 Java Swing 主题会导致 JTable 错误

android - 致命异常 : main

android - Android Gradle库 'failure to resolve'

firebase - 如何使用 ionic 3 设置 Firebase 分析事件

java - 为多个并发 SOAP 请求配置 Tomcat

java - SqlServer遇到异常 "VARCHAR"

android - 我如何从安卓手机接收网站的值(value)

android - 如何将 onClickListener 设置为 kotlin 中的按钮

android - Firebase 插件错误 400 错误 : invalid_scope into android studio

java - "Failed to resolve: com.google.firebase:firebase-core:9.0.0"