如何处理FirebaseAuthUserCollisionException

Gui*_*FGL 5 android facebook facebook-graph-api firebase firebase-authentication

FirebaseAuthUserCollisionException当我尝试在Android应用程序中使用Facebook登录时,我开始遇到异常.

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

我使用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();
                        }
                    }
                }
            });
}
Run Code Online (Sandbox Code Playgroud)

我的Gradle文件与当前使用库:

compile 'com.google.firebase:firebase-auth:10.2.1'
compile 'com.facebook.android:facebook-android-sdk:[4,5)'
Run Code Online (Sandbox Code Playgroud)

所以我的问题是:我不知道如何处理FirebaseAuthUserCollisionException异常.

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

boj*_*eil 7

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

当你使用时会发生这种情况single accounts per email.如果要为每封电子邮件允许不同的帐户,可以切换到multiple accounts per emailFirebase控制台.

这是一个例子:

mAuth.signInWithCredential(authCredential)
    .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
        @Override
        public void onComplete(@NonNull Task<AuthResult> task) {
            // Account exists with different credential. Assume the developer wants to
            // continue and link new credential to existing account.
            if (!task.isSuccessful() &&
                task.getException() instanceof FirebaseAuthUserCollisionException) {
                FirebaseAuthUserCollisionException exception =
                        (FirebaseAuthUserCollisionException)task.getException();
                if (exception.getErrorCode() == 
                    ERROR_ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL) {
                    // Lookup existing account’s provider ID.
                    mAuth.fetchProvidersForEmail(existingAcctEmail)
                       .addOnCompleteListener(new OnCompleteListener<ProviderQueryResult> {
                          @Override
                          public void onComplete(@NonNull Task<ProviderQueryResult> task) {
                            if (task.isSuccessful()) {
                              if (task.getResult().getProviders().contains(
                                      EmailAuthProvider.PROVIDER_ID)) {
                                // Password account already exists with the same email.
                                // Ask user to provide password associated with that account.
                                ... 
                                // Sign in with email and the provided password.
                                // If this was a Google account, call signInWithCredential instead.
                                mAuth.signInWithEmailAndPassword(existingAcctEmail, password)
                                  addOnCompleteListener(new OnCompleteListener<AuthResult> {
                                    @Override
                                    public void onComplete(@NonNull Task<AuthResult> task) {
                                      if (task.isSuccessful()) { 
                                        // Link initial credential to existing account.
                                        mAuth.getCurrentUser().linkWithCredential(authCredential);
                                      }
                                    }
                                  });
                              }
                            }
                          }
                        });
            }
        }
    });
Run Code Online (Sandbox Code Playgroud)

  • 我添加了一个例子。 (2认同)
  • 在我的情况下,用户已经注册了Facebook提供程序,那么将没有密码。关于“ existingAcctEmail”,在哪里可以得到它? (2认同)