繁体   English   中英

登录使用电子邮件和密码创建的 firebase 帐户时密码消失

[英]Password is gone when logging in a firebase account that was created using Email and Password

我创建了一个支持电子邮件/密码和 Google 身份验证的应用程序。 我发现如果我以第一种方式创建了一个帐户,但退出并再次使用 Google 登录,原始密码就消失了,并且无法再使用电子邮件登录。 有什么办法可以避免吗?

// Google authentication
const signInWithGoogle = useCallback(
      async event => {
        event.preventDefault();
        const provider = new firebase.auth.GoogleAuthProvider();
        try {
          await firebaseApp
          .auth()
          .signInWithRedirect(provider)
          .then(function(result) {
            var user = result.user.providerId;
            alert(user);
          });
          history.push("/transfer");
        } catch(error) {
          alert(error.message);
        }
      },
      [history]
    );
//Email/Password sign-in
const handleLogin = useCallback(
        async event => {
          event.preventDefault();
          const { email, password } = event.target.elements;
          try {
            await firebaseApp
              .auth()
              .signInWithEmailAndPassword(email.value, password.value)
              .then(function(result) {
                var user = result.user.providerId;
                alert(user);
              });
            history.push("/transfer");
          } catch (error) {
            alert(error);
          }
        },
        [history]
      );
// Email/Password sign-up
const handleSignUp = useCallback(async event => {
      event.preventDefault();
      const { email, password } = event.target.elements;
      try {
        await firebaseApp
          .auth()
          .createUserWithEmailAndPassword(email.value, password.value);
        history.push("/usersignupcred");
      } catch (error) {
        alert(error);
      }
    }, [history]);

这里的文件中可以看到这样的解释:

请注意,某些提供商(例如 Google 和 Microsoft)同时充当电子邮件和社交身份提供商。 电子邮件提供商被视为对其托管电子邮件域相关的所有地址具有权威性。 这意味着使用由同一提供商托管的电子邮件地址登录的用户永远不会出现此错误(例如,使用 @gmail.com 电子邮件登录 Google,或使用 @live.com 或 @outlook.com 电子邮件登录 Microsoft )。

我建议使用与文档中类似的方法:

// User tries to sign in with Facebook.
auth.signInWithPopup(new firebase.auth.FacebookAuthProvider()).catch(err => {
  // User's email already exists.
  if (err.code === 'auth/account-exists-with-different-credential') {
    // The pending Facebook credential.
    var pendingCred = err.credential;
    // The provider account's email address.
    var email = err.email;
    // Get the sign-in methods for this email.
    auth.fetchSignInMethodsForEmail(email).then(methods => {
      // If the user has several sign-in methods, the first method
      // in the list will be the "recommended" method to use.
      if (methods[0] === 'password') {
        // TODO: Ask the user for their password.
        // In real scenario, you should handle this asynchronously.
        var password = promptUserForPassword();
        auth.signInWithEmailAndPassword(email, password).then(result => {
          return result.user.linkWithCredential(pendingCred);
        }).then(() => {
          // Facebook account successfully linked to the existing user.
          goToApp();
        });
        return;
      }
      // All other cases are external providers.
      // Construct provider object for that provider.
      // TODO: Implement getProviderForProviderId.
      var provider = getProviderForProviderId(methods[0]);
      // At this point, you should let the user know that they already have an
      // account with a different provider, and validate they want to sign in
      // with the new provider.
      // Note: Browsers usually block popups triggered asynchronously, so in
      // real app, you should ask the user to click on a "Continue" button
      // that will trigger signInWithPopup().
      auth.signInWithPopup(provider).then(result => {
        // Note: Identity Platform doesn't control the provider's sign-in
        // flow, so it's possible for the user to sign in with an account
        // with a different email from the first one.

        // Link the Facebook credential. We have access to the pending
        // credential, so we can directly call the link method.
        result.user.linkWithCredential(pendingCred).then(usercred => {
          // Success.
          goToApp();
        });
      });
    });
  }
});

但是不要等待引发错误(如果使用谷歌登录,则不会引发任何错误,正如您在您的情况中所解释的那样)尝试始终先调用fetchSignInMethodsForEmail并且如果用户具有email提供商并现在尝试首先使用谷歌让他通过电子邮件提供商登录,然后将他与 Google 提供商联系起来。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM