草庐IT

android - 如何处理 FirebaseAuthUserCollisionException

coder 2023-12-11 原文

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

com.google.firebase.auth.FirebaseAuthUserCollisionException: An account already exists with the same email address but different sign-in credentials. Sign in using a provider associated with this email address.

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

这些登录方法已经有效。我能够在 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 文档中的解决方案都没有帮助我。我正在寻找一种解决方案,该解决方案能够通过重复的凭据登录用户,以仍然提供“一键式”登录方法。

最佳答案

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

当您使用每个电子邮件的单个帐户 时会发生这种情况。如果您想允许每封电子邮件使用不同的帐户,您可以在 Firebase 控制台中切换到每封电子邮件多个帐户

这是一个例子:

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);
                                      }
                                    }
                                  });
                              }
                            }
                          }
                        });
            }
        }
    });

关于android - 如何处理 FirebaseAuthUserCollisionException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46322998/

有关android - 如何处理 FirebaseAuthUserCollisionException的更多相关文章

  1. ruby-on-rails - Enumerator.new 如何处理已通过的 block ? - 2

    我在理解Enumerator.new方法的工作原理时遇到了一些困难。假设文档中的示例:fib=Enumerator.newdo|y|a=b=1loopdoy[1,1,2,3,5,8,13,21,34,55]循环中断条件在哪里,它如何知道循环应该迭代多少次(因为它没有任何明确的中断条件并且看起来像无限循环)? 最佳答案 Enumerator使用Fibers在内部。您的示例等效于:require'fiber'fiber=Fiber.newdoa=b=1loopdoFiber.yieldaa,b=b,a+bendend10.times.m

  2. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  3. ruby-on-rails - 如何处理 Grape 中特定操作的过滤器之前? - 2

    我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?

  4. Ruby - 如何处理子类意外覆盖父类(super class)私有(private)字段的问题? - 2

    假设您编写了一个类Sup,我决定将其扩展为SubSup。我不仅需要了解你发布的接口(interface),还需要了解你的私有(private)字段。见证这次失败:classSupdefinitialize@privateField="fromsup"enddefgetXreturn@privateFieldendendclassSub问题是,解决这个问题的正确方法是什么?看起来子类应该能够使用它想要的任何字段而不会弄乱父类(superclass)。编辑:equivalentexampleinJava返回"fromSup",这也是它应该产生的答案。 最佳答案

  5. ruby-on-rails - 我如何处理 View 中的 nils? - 2

    我设置了以下模型:classContact:no_freq?validates_presence_of:freq,:if=>:no_band?protecteddefno_freq?freq.nil?enddefno_band?band.nil?endendclassBand当我在我的新View中输入频率时,如果输入了频率,则不允许指定波段。这在我的其他观点中造成了问题,因为band现在为零。我如何允许不指定band并在我的index和showView中显示为空,然后在editView中允许在以后指定一个。通过执行以下操作,我已经能够让我的索引显示空白:contact.band&&co

  6. ruby - 如何处理树顶左递归 - 2

    我有一个grammarfile对于我正在尝试构建的一种新的通用编程语言。我正在努力使该语言健壮且易于使用(它深受Ruby等启发),为此我引入了一些左递归规则。我看到一些例子似乎表明了以下左递归规则:rulel_recursel_recurse/'somethingelse'end可以通过将其更改为非左递归:ruler_recurse'somethingelse'/r_recurseend对我来说,这看起来会有不同的问题并且仍然会失败。我是对的,还是这会“奏效”?我试图(查找和)消除的特定左递归可以在这个grammarfile中找到.我不确定哪些规则受到影响,但至少somewerepoi

  7. ruby - Ruby 如何处理嵌套类的继承? - 2

    在下面的测试用例中:classPackageclassComponentdefinitializep[:initialize,self]endendendclassPackage_A结果:[:initialize,#]#[:initialize,#]#如何获取特定的Package_A.component和Package_B.component? 最佳答案 ClassComponent是在Package中声明的,所以看起来是正确的。::指示在Package_A范围内查找名称Component。由于那里没有Component,它会查找父

  8. c - 如何处理 ruby​​ ffi gem 中的 ruby​​ 数组? - 2

    我想使用ruby​​ffigem调用一个c函数,该函数将一个数组作为输入变量,输出是一个数组。也就是说,c函数看起来像:double*my_function(doublearray[],intsize)我创建了ruby​​绑定(bind):moduleMyModuleextendFFI::Libraryffi_lib'c'ffi_lib'my_c_lib'attach_function:my_function,[:pointer,int],:pointer我想用ruby​​代码调用:result_array=MyModule.my_function([4,6,4],3)我该怎么做?

  9. ruby - Smalltalk 如何处理 monkeypatching? - 2

    我是一名Ruby程序员。对我来说,monkeypatching是在运行时更改外部项目中的类或模块方法。我感兴趣的是,您有什么机制可以保护您免受某些滥用该优良特性的影响。以下是我遇到的一些场景,其中monkeypatching让我很头疼。虽然我根本不知道Smalltalk,但这种语言早在Ruby出现之前就已经存在了。我做了一些研究,看看Smalltalk是否以及如何解决其中的一些问题,但在Google上没有找到太多。所以我在这里,询问Smalltalkers是否可以分享他们的智慧。场景A:bug修复冲突项目A和B依赖于项目C。项目C有一个错误。项目A和B版本包含对项目C的修复。如果您的代

  10. ruby-on-rails - 验证事件连接!在 Rails 4 中已弃用,我们应该如何处理该功能? - 2

    我一直在关注这篇文章以与工头一起设置puma:https://www.digitalocean.com/community/articles/how-to-set-up-zero-downtime-rails-deploys-using-puma-and-foremanpuma脚本在连接后告诉verify_active_connections!但它在rails4中不可用。注释掉方法调用将使脚本运行但我不确定这是否会泄漏资源.关于这个问题,我能看到的唯一文档是:https://github.com/socialcast/resque-ensure-connected/issues/3但是

随机推荐