首页 > 解决方案 > Google 登录会删除现有的用户数据

问题描述

我正在使用 Firebase 身份验证和 Cloud Firestore 构建一个 Android 应用程序。该应用程序有多个身份验证提供者;用户可以使用其注册的电子邮件和密码登录,也可以使用 Google 或 Facebook 登录。

那么问题来了: 当用户第一次使用自己注册的电子邮件和密码登录时,他会将自己的详细信息存储在 Firestore 中的文档中。现在,如果同一用户注销并使用 Google 登录(链接到同一电子邮件地址),则登录成功,但 Firestore 文档消失了;被 Google 登录提供的数据覆盖/替换。甚至注册的 Firebase EmailAuth 详细信息也不见了;全部被 Google 登录客户端覆盖。

我注意到的一件事是,当我上面提到的事情发生时,电子邮件身份验证和谷歌登录身份验证(具有相同的电子邮件地址)在我的控制台的 Firebase 身份验证页面中具有相同的用户 UID。

我想要的是: 用户使用他注册的电子邮件和密码登录,然后注销。当他通过 Google 登录时,如果已经注册了相同的电子邮件地址,则需要有一个错误 toast 阻止他通过 Google 登录。基本上,如果他的电子邮件地址已经注册,那么他只能通过电子邮件和密码验证登录,而不能通过谷歌登录。

Facebook 在这种情况下提供帮助;如果已注册相同的电子邮件地址,则不会登录,而是会给出等效于“此电子邮件地址已与另一个帐户存在”的错误。我想和谷歌在这里做同样的事情。

如果我的问题不是很清楚,试试这个:https ://github.com/firebase/firebase-android-sdk/issues/25

(是的,我注意到他们用“预期行为”结束了这个问题,这正是我发布这个问题的原因;我需要一种解决方法来解决这个问题,让它做我需要的事情)。

标签: javaandroidfirebasefirebase-authenticationgoogle-authentication

解决方案


我想要的是用户使用他注册的电子邮件和密码登录,然后注销。当他通过 Google 登录时,如果已经注册了相同的电子邮件地址,则需要有一个错误 toast 阻止他通过 Google 登录。基本上,如果他的电子邮件地址已经注册,那么他只能通过电子邮件和密码验证登录,而不能通过谷歌登录。

解决这个问题的流程是从一开始就询问用户的电子邮件地址。获得电子邮件地址后,您可以检查用户是否已有帐户。假设您对每个身份验证提供程序都有不同的按钮,您可以根据用户第一次为身份验证选择的内容来显示或隐藏它们。例如,如果用户选择了使用电子邮件和密码进行身份验证,请检查是否使用:

auth.fetchSignInMethodsForEmail(email).addOnCompleteListener(signInMethodsTask -> {
    if (signInMethodsTask.isSuccessful()) {
        List<String> signInMethods = signInMethodsTask.getResult().getSignInMethods();
        for (String signInMethod : signInMethods) {
            switch (signInMethod) {
                case GoogleAuthProvider.PROVIDER_ID:
                    googleSignInButton.setVisibility(VISIBLE);
                    facebookSignInButton.setVisibility(GONE);
                    passwordSignInButton.setVisibility(GONE);
                    break;
                case FacebookAuthProvider.PROVIDER_ID:
                    googleSignInButton.setVisibility(GONE);
                    facebookSignInButton.setVisibility(VISIBLE);
                    passwordSignInButton.setVisibility(GONE);
                    break;
                case EmailAuthProvider.PROVIDER_ID:
                    googleSignInButton.setVisibility(GONE);
                    facebookSignInButton.setVisibility(GONE);
                    passwordSignInButton.setVisibility(VISIBLE);
                    break;
                default:
                    googleSignInButton.setVisibility(VISIBLE);
                    facebookSignInButton.setVisibility(VISIBLE);
                    passwordSignInButton.setVisibility(VISIBLE);
                    break;
            }
        }
    } 
});

在 的情况下EmailAuthProvider.PROVIDER_ID,隐藏其他按钮并仅显示提供电子邮件和密码登录的按钮。如果用户是新用户,则显示所有按钮,以便用户可以选择一个或其他身份验证选项。

PS 如果您只想让用户使用特定的提供商登录,则无需让用户选择使用其他提供商登录。


推荐阅读