最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Firebase logging in with new provider (Google) removes previous provider (password) - Stack Overflow

programmeradmin2浏览0评论

I'm making a login with Firebase (v3) Auth and I hit this problem:

  1. User signs up initially with email and password.
  2. Logout.
  3. Later, sign in with Google.

I would expect an error complaining that the e-mail address is used for a different account, and then ask the user to type the password to then link the accounts, but instead Firebase silently removes the email/password login method and returns a success message.

Code for authentication with Google:

var provider = new firebase.auth.GoogleAuthProvider();
firebase.auth().signInWithPopup(provider).then(
    result => {
        console.log("federated (google) result", result);
    },
    error => {
        console.log("federated (google) error", error);
    }
);

Code for authentication with email and password:

// Login:
firebase.auth().signInWithEmailAndPassword(this.state.email, this.state.password).then(
    ok => {
        console.log("email/pass sign in success", ok);
    },
    error => {
        console.log("email/pass sign in error", error);
    }
)

// Register:
firebase.auth().createUserWithEmailAndPassword(this.state.email, this.state.password).then(
    ok => {
        console.log("Register OK", ok);
    },
    error => {
        console.log("Register error", error);
    }
)

I see in the guide that account linking is done by first signing in a user with their current provider/method and only then ask for credentials/obtain tokens for the new authentication method/provider. In my case, I don't know if they have other authentication providers until too late (Firebase overwrites it).

Is there a way to detect the email is already taken before Firebase overwrites the details of the already existing account and ask the user to type their password and link the accounts? Or, even better, link the accounts automatically given they have logged in with Google and email addresses match?

I'm making a login with Firebase (v3) Auth and I hit this problem:

  1. User signs up initially with email and password.
  2. Logout.
  3. Later, sign in with Google.

I would expect an error complaining that the e-mail address is used for a different account, and then ask the user to type the password to then link the accounts, but instead Firebase silently removes the email/password login method and returns a success message.

Code for authentication with Google:

var provider = new firebase.auth.GoogleAuthProvider();
firebase.auth().signInWithPopup(provider).then(
    result => {
        console.log("federated (google) result", result);
    },
    error => {
        console.log("federated (google) error", error);
    }
);

Code for authentication with email and password:

// Login:
firebase.auth().signInWithEmailAndPassword(this.state.email, this.state.password).then(
    ok => {
        console.log("email/pass sign in success", ok);
    },
    error => {
        console.log("email/pass sign in error", error);
    }
)

// Register:
firebase.auth().createUserWithEmailAndPassword(this.state.email, this.state.password).then(
    ok => {
        console.log("Register OK", ok);
    },
    error => {
        console.log("Register error", error);
    }
)

I see in the guide that account linking is done by first signing in a user with their current provider/method and only then ask for credentials/obtain tokens for the new authentication method/provider. In my case, I don't know if they have other authentication providers until too late (Firebase overwrites it).

Is there a way to detect the email is already taken before Firebase overwrites the details of the already existing account and ask the user to type their password and link the accounts? Or, even better, link the accounts automatically given they have logged in with Google and email addresses match?

Share Improve this question edited May 25, 2016 at 9:19 Vlad V asked May 23, 2016 at 16:35 Vlad VVlad V 1,6541 gold badge14 silver badges28 bronze badges 2
  • Since Firebase 3 allows you to log in using different mchanisms .. you may want to LINK the different mechanisms together to have a unified view. Refer to firebase.google.com/docs/auth/android/account-linking – ErstwhileIII Commented May 24, 2016 at 22:26
  • 1 That's correct. I wanted to link different mechanisms but specifically the issue (or confusion, see answer) was what happens when the user already has a account with mechanism A (say email/password) and the next time he visits, forgets about it, and signs in with method B (say Google). The email addresses are the same, so the accounts should be linked automatically (as programatically you don't know there is an account with that e-mail already during sign-in), or the sign in should return an error so you can put some login to deal with this issue. I wrote in my answer what actually happens. – Vlad V Commented May 25, 2016 at 9:17
Add a comment  | 

2 Answers 2

Reset to default 22

I figured it out. Firebase behaves as it should and this was not a technical/coding problem. It's more of a documentation issue.

When a user signs up with email and password, logs out and signs in with a different method (that wasn't used before), two things can happen:

  1. If the email is confirmed, the email/password credentials are remembered when you login with a new provider (the desired outcome in my question).

or

  1. If the email is unconfirmed, the user is updated such that the email/password credentials are removed and the new login method will be kept. User details like displayName are not updated automatically.

You can try using FirebaseAuth.instance.fetchSignInMethodsForEmail(email) to get a list of all the Auth Methods that this email is linked with. Then you can just check all the auth methods and write logic considering that.

// After asking the user for their email.
var email = window.prompt('Please provide your email');
firebase.auth().fetchSignInMethodsForEmail(email)
  .then((signInMethods) => {
    // This returns the same array as fetchProvidersForEmail but for email
    // provider identified by 'password' string, signInMethods would contain 2
    // different strings:
    // 'emailLink' if the user previously signed in with an email/link
    // 'password' if the user has a password.
    // A user could have both.
    if (signInMethods.indexOf(
            firebase.auth.EmailAuthProvider.EMAIL_PASSWORD_SIGN_IN_METHOD) != -1) {
      // User can sign in with email/password.
    }
    if (signInMethods.indexOf(
            firebase.auth.EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD) != -1) {
      // User can sign in with email/link.
    }
  })
  .catch((error) => {
    // Some error occurred, you can inspect the code: error.code
  });

I could not found FlutterFire Docs for this, but I found Web Docs for this. You can use it in Flutter as well.

Follow this link to documentation: fetchSignInMethodsForEmail()

发布评论

评论列表(0)

  1. 暂无评论