【问题标题】:How do you link firebase accounts in firebase_auth 0.11.1 in flutter?如何在颤振中链接 firebase_auth 0.11.1 中的 firebase 帐户?
【发布时间】:2019-10-09 03:27:58
【问题描述】:

我已经使用 firebase_auth 0.11.0 成功实现了 Flutter 的 Google 和 Facebook 登录。我需要为具有相同电子邮件地址的帐户实现关联帐户功能。

Future<FirebaseUser> _signInWithGoogle() async {
  final GoogleSignInAccount googleUser = await _googleSignIn.signIn();
  final GoogleSignInAuthentication googleAuth = await googleUser.authentication;

  final AuthCredential credential = GoogleAuthProvider.getCredential(
  accessToken: googleAuth.accessToken,
  idToken: googleAuth.idToken,
);

final FirebaseUser user = await _auth.signInWithCredential(credential);

您如何/在哪里捕获该帐户是重复电子邮件并因此需要 linkwithcredential 函数的 Firebase 错误 (auth/account-exists-with-different-credential)?我试图在上面的signInWithCredential_signInWithGoogle() 上捕获错误,但无济于事。

基于此处的示例:

https://github.com/flutter/plugins/blob/06256967e494e6d719023a249c8bdaae4b3ae065/packages/firebase_auth/test/firebase_auth_test.dart

FirebaseUser user = await auth.currentUser(); user = await user.linkWithCredential(credential);

这是您链接帐户的方式,但我的问题是您如何确定需要运行此功能?

编辑:为清楚起见,我可以在仅存在一个凭据/会话时链接帐户吗?例如,流程应该是,用 Facebook 登录,捕获 (ERROR_ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL),然后链接到 Google。

【问题讨论】:

    标签: flutter firebase-authentication


    【解决方案1】:

    获取当前用户的provider ID列表,如果有FB但没有Google,则可以链接Google

    List&lt;UserInfo&gt; providerList = _auth.currentUser().providerData;


    //用crecentials捕获登录错误,检查错误类型,采取行动 /// 可能的错误:

    • ERROR_INVALID_CREDENTIAL - 如果凭证数据格式错误或已过期。
    • ERROR_USER_DISABLED - 如果用户已被禁用(例如,在 Firebase 控制台中)
    • ERROR_ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL - 如果已经存在具有 Google 声明的电子邮件地址的帐户。通过调用 [fetchSignInMethodsForEmail] 然后要求用户使用其中一个登录来解决这种情况。只有在 Firebase 控制台中启用了“每个电子邮件地址一个帐户”设置(推荐)时,才会引发此错误。
    • ERROR_OPERATION_NOT_ALLOWED - 表示未启用 Google 帐户。
    • ERROR_INVALID_ACTION_CODE - 如果链接中的操作代码格式错误、已过期或已被使用。

    final onError = (exception, stacktrace) { /*ERROR HANDLING*/ };

    final FirebaseUser user = await _auth.signInWithCredential(credential).catchError(onError);

    【讨论】:

    • 我发现有两种情况可以解决这个问题。 a) 如果我在 Firebase 控制台中启用每个电子邮件地址一个帐户,我可以使用 _auth.signInWithCredential 捕获错误 ERROR_ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL,问题是如何从这里链接它们,因为用户从未登录,当前用户为空。 b)如果我在控制台中允许多个帐户,它会创建两个帐户,我可以从提供者数据中提取电子邮件,但 firebase 用户对象本身没有电子邮件。在这种情况下 currentuser.providerdata 有电子邮件但 firebase 用户 user.email 为空。
    • 我的后续问题是,在捕获 ERROR_ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL 之后,linkwithcredential 是否是一个有效的工作流程?
    • 我正在尝试这样的事情,但是由于他们已将 linkwithcredential 移至用户,因此我没有当前用户来链接 FirebaseUser user = await _auth.signInWithCredential(credential) .catchError ((e) async { if(e.code == 'ERROR_ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL') { FirebaseUser user = await _auth.currentUser(); user.linkWithCredential(credential); } print(e.message + "MESSAGE"); print(e .code + 'CODE'); print(e.details); });
    • 我有这个:` GoogleSignInAccount user = _googleSignIn.currentUser; if (user == null) { user = await _googleSignIn.signIn().catchError(onError); if(user != null){ final GoogleSignInAuthentication googleAuth = await user.authentication; FirebaseUser firebaseUser = await _auth.signInWithCredential(GoogleAuthProvider.getCredential(accessToken: googleAuth.accessToken, idToken: googleAuth.idToken, )).catchError(onError); `
    • 如果你尝试用谷歌登录用户并且你得到ERROR_ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL,你可以通知用户需要链接FB帐户,你开始FB登录,在获得凭据后你得到当前用户用户(已使用 Google 登录),并将 Facebook 链接到该用户,链接后您应该会在 Firebase 上看到两个图标
    【解决方案2】:

    要链接 google 和 facebook,我使用的是:

    FacebookLoginResult facebookLoginResult = await _handleFBSignIn();
        final accessToken = facebookLoginResult.accessToken.token;
        if (facebookLoginResult.status == FacebookLoginStatus.loggedIn) {
          final facebookAuthCred =
          FacebookAuthProvider.getCredential(accessToken: accessToken);
    
          final user = await auth.signInWithCredential(facebookAuthCred).catchError((e) async {
            if (e.code == 'ERROR_ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL') {
              var graphResponse = await http.get(
                  'https://graph.facebook.com/v2.12/me?fields=name,first_name,last_name,email,picture.width(400)&access_token=${facebookLoginResult
                      .accessToken.token}');
              Map<String, dynamic> profile = json.decode(graphResponse.body);
              profileData = profile;
    
              var email = profile["email"];
    
              final signInMethods = await FirebaseAuth.instance
                  .fetchSignInMethodsForEmail(email: email);
              if (signInMethods.contains("google.com")) {
                final authGoogleResult = await googleLogin();
    
                if (authGoogleResult.user.email == e.email) {
                  await authGoogleResult.user.linkWithCredential(e.credential);
                }
              }
            }
          });
    

    【讨论】:

    • 所以用户,如果他已经有一个谷歌帐户。必须 - 使用 Facebook 登录,然后 - 使用 Google 登录。没有其他方法可以在不让用户登录两个服务的情况下链接帐户?
    • 现在不是使用ERROR_ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL,而是使用account-exists-with-different-credential
    【解决方案3】:

    基于此信息:Linking multiple auth providers with Firebase on Login

    (如果仍然准确)我的流程无法实现,即您无法在未登录第一个 firebase 帐户的情况下链接帐户,例如登录 Google THEN 登录并链接 Facebook。

    我需要的用户流程需要通过为同一封电子邮件启用多个帐户来实现。尽管这会带来额外的问题,但第二个 firebase 帐户用户 FirebaseUser user 不包含电子邮件,user.emailnull。虽然user.providerData 有邮箱。

    【讨论】:

      猜你喜欢
      • 2019-11-05
      • 2022-08-23
      • 2020-07-13
      • 2022-11-12
      • 2017-12-04
      • 2021-11-24
      • 2020-04-18
      • 2018-03-17
      • 1970-01-01
      相关资源
      最近更新 更多