首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何处理FirebaseAuthUserCollisionException

如何处理FirebaseAuthUserCollisionException
EN

Stack Overflow用户
提问于 2017-09-20 13:11:05
回答 2查看 4K关注 0票数 10

当我尝试在我的FirebaseAuthUserCollisionException 应用程序中注册Facebook时,我开始得到一个异常。

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

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

这些登录方法已经奏效了。我能够在Facebook注册一个帐户,并使用同样的方法登录这个帐户。但现在已经开始抛出这个异常了。

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

代码语言:javascript
复制
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文件:

代码语言:javascript
复制
compile 'com.google.firebase:firebase-auth:10.2.1'
compile 'com.facebook.android:facebook-android-sdk:[4,5)'

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

StackOverflow或Firebase文档中的任何解决方案都帮不了我。我正在寻找一个解决方案,能够登录用户虽然重复的凭证,仍然交付“一键”登录方法。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-09-22 08:23:40

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

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

下面是一个示例:

代码语言:javascript
复制
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);
                                      }
                                    }
                                  });
                              }
                            }
                          }
                        });
            }
        }
    });
票数 16
EN

Stack Overflow用户

发布于 2020-07-15 23:02:11

没有必要这样做,您可以只允许多个帐户合并在防火墙下->认证->登录方法->高级->更改(每个电子邮件地址多个帐户。

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

见下面的样本。

代码语言:javascript
复制
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);
                }
            });
票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46322998

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档