简体   繁体   English

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

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

I created an app that supports both Email/Password and Google authentication.我创建了一个支持电子邮件/密码和 Google 身份验证的应用程序。 I found that if I created an account in a first way, but logged out and in again with Google, the origin password was gone, and no way to sign in with email anymore.我发现如果我以第一种方式创建了一个帐户,但退出并再次使用 Google 登录,原始密码就消失了,并且无法再使用电子邮件登录。 Is there any way to avoid so?有什么办法可以避免吗?

// 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]);

Here in the documentation you can see this explanation: 这里的文件中可以看到这样的解释:

Note that some providers, such as Google and Microsoft, serve as both email and social identity providers.请注意,某些提供商(例如 Google 和 Microsoft)同时充当电子邮件和社交身份提供商。 Email providers are considered authoritative for all addresses related to their hosted email domain.电子邮件提供商被视为对其托管电子邮件域相关的所有地址具有权威性。 This means a user logging in with an email address hosted by the same provider will never raise this error (for example, signing in with Google using an @gmail.com email, or Microsoft using an @live.com or @outlook.com email).这意味着使用由同一提供商托管的电子邮件地址登录的用户永远不会出现此错误(例如,使用 @gmail.com 电子邮件登录 Google,或使用 @live.com 或 @outlook.com 电子邮件登录 Microsoft )。

I would recommend to use as similar approach like here from the docu:我建议使用与文档中类似的方法:

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

But instead of waiting for the error to be raised (none will be raised if using Google login as you also explained in your case) try always to call first fetchSignInMethodsForEmail and if the user has the email provider and tries now to use the Google one first log him in with the email provider and link him later with the Google provider.但是不要等待引发错误(如果使用谷歌登录,则不会引发任何错误,正如您在您的情况中所解释的那样)尝试始终先调用fetchSignInMethodsForEmail并且如果用户具有email提供商并现在尝试首先使用谷歌让他通过电子邮件提供商登录,然后将他与 Google 提供商联系起来。

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

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