如何处理FirebaseAuthUserCollisionException

时间:2017-09-20 13:11:05

标签: android facebook firebase facebook-graph-api firebase-authentication

当我尝试在 Android 应用程序中使用 Facebook 登录时,我开始收到FirebaseAuthUserCollisionException个例外。

  

com.google.firebase.auth.FirebaseAuthUserCollisionException:An   帐户已存在且电子邮件地址相同但不同   登录凭据。使用与此关联的提供商登录   电子邮件地址。

我正在使用 Firebase 处理注册,而Facebook则使用com.facebook.login.widget.LoginButton视图作为触发器,提供“一键式”登录方式。

这些登录方法已经有效。我能够在Facebook注册一个帐户,并使用相同的方法登录此帐户。但现在已经开始抛出这个例外了。

以下是我从Facebook注册帐户并继续登录的代码:

private void handleFacebookAccessToken(AccessToken token) {
    final ProgressDialog dialog = new ProgressDialog(this);
    dialog.show(getString(R.string.dialog_wait));
    firebaseAuth.signInWithCredential(FacebookAuthProvider.getCredential(token.getToken()))
            .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                @SuppressWarnings("ThrowableResultOfMethodCallIgnored")
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        dialog.close();
                        registerNewUserFromSocialLogin(firebaseAuth.getCurrentUser());
                    } else {
                        if(task.getException() instanceof FirebaseAuthUserCollisionException) {

                            //TODO: handle sign-in with different credentials

                        } else {
                            dialog.close();
                            LoginManager.getInstance().logOut();
                            Toast.makeText(LoginActivity.this,
                                    R.string.error_login,
                                    Toast.LENGTH_SHORT).show();
                        }
                    }
                }
            });
}

我的Gradle文件包含当前使用库:

compile 'com.google.firebase:firebase-auth:10.2.1'
compile 'com.facebook.android:facebook-android-sdk:[4,5)'

所以我的问题是:我不知道如何处理FirebaseAuthUserCollisionException例外。

StackOverflow或Firebase文档中的所有解决方案都不能帮助我。我正在寻找能够登录用户的解决方案,尽管是重复的凭证,但是stil提供了“一键式”登录方法。

3 个答案:

答案 0 :(得分:7)

当用户之前使用其他提供商使用相同的电子邮件登录时,您将收到该错误。例如,用户使用Google登录电子邮件user@gmail.com。然后,用户尝试使用相同的电子邮件登录,但使用Facebook。 Firebase Auth后端将返回该错误(帐户存在不同的凭据)。在这种情况下,您应该使用readfile()查找与email user@gmail.com相关联的现有提供商,在本例中为fetchProvidersForEmail。您google.com到现有的Google帐户以证明该帐户的所有权,然后signInWithCredential用户最初尝试登录的Facebook凭据。这将合并两个帐户,以便将来用户可以使用其中一个登录。

使用linkWithCredential时会发生这种情况。如果您希望每封电子邮件允许使用不同的帐户,则可以在Firebase控制台中切换为single accounts per email

以下是一个例子:

multiple accounts per email

答案 1 :(得分:0)

最简单的方法是预先进行检查-我尝试先使用任何获得的凭据登录,并仅在不存在时创建一个新帐户

AuthCredential credential //... Obtain whatever

auth.signInWithCredential(credential).addOnCompleteListener(new OnCompleteListener<AuthResult>() {
    @Override
    public void onComplete(@NonNull Task<AuthResult> task) {
        if (task.isSuccessful()) {
            Log.d(TAG, "Credential login succeeded (no new account)");
            ... //success logic
        } else {
            Log.e(TAG, "Failed to login with credential, attempting a new account instead. (" + task.getException() + ")");
            auth.getCurrentUser().linkWithCredential(credential).addOnCompleteListener(getActivity(), ...); //use the same callback as you usually would
        }
    }
});

答案 2 :(得分:-2)

无需这样做,您只需要在firebaase-> authentication->登录方法-> Advanced-> change(每个电子邮件地址多个帐户)下允许多个帐户合并即可。

Firebase将合并相同的电子邮件地址,但将为您提供不同的用户UID。

请参见下面的示例。

AuthCredential authCredential =  FacebookAuthProvider.getCredential(token.getToken());
    
    mAuth.signInWithCredential(authCredential)
            .addOnCompleteListener(this, task -> {
                if (task.isSuccessful()) {
                    // Sign in success, update UI with the signed-in user's information
                    Log.d(TAG, "signInWithCredential:success");
                    FirebaseUser user = mAuth.getCurrentUser();
                    LoginFacebookGoogleActivity.this.updateUI(user);
                } else {
                    // If sign in fails, display a message to the user.
                    Log.w(TAG, "signInWithCredential:failure", task.getException());

                    if(task.getException() instanceof FirebaseAuthUserCollisionException){
                        FirebaseAuthUserCollisionException exception = (FirebaseAuthUserCollisionException) task.getException();

                        //log this bundle into the analytics to analyze which details you want to collect
                        
                    }

                    Toast.makeText(LoginFacebookGoogleActivity.this, "Authentication failed " + task.getException(), Toast.LENGTH_SHORT).show();
                    LoginFacebookGoogleActivity.this.updateUI(null);
                }
            });