41

Using Firebase for web I can successfully create an anonymous user. I can also create a new email/password user. But when trying to convert an anonymous user to a email/password user I get error:

auth/provider-already-linked
User can only be linked to one identity for the given provider.

Firebase documents the procedure here under section "Convert an anonymous account to a permanent account" here: https://firebase.google.com/docs/auth/web/anonymous-auth

Here's the account link code. Anonymous user is signed in.

return firebase.auth().createUserWithEmailAndPassword(email, password).then(newUser => {

    // Credential is being successfully retrieved. Note "any" workaround until typescript updated.
    let credential = (<any>firebase.auth.EmailAuthProvider).credential(email, password);

    firebase.auth().currentUser.link(credential)
        .then(user => { return user; })
        .catch(err => console.log(err)); // Returns auth/provider-already-linked error.
});

3 Answers 3

72

You should not call createUserWithEmailAndPassword to upgrade the anonymous user. This will sign up a new user, signing out the currently signed in anonymous user.

All you need is the email and password of the user. IDP providers (e.g. Google, Facebook), on the contrary, will require to complete their full sign in flow to get their tokens to identify the user. We do recommend to use linkWithPopup for these, though.

Example:

// (Anonymous user is signed in at that point.)

// 1. Create the email and password credential, to upgrade the
// anonymous user.
var credential = firebase.auth.EmailAuthProvider.credential(email, password);

// 2. Links the credential to the currently signed in user
// (the anonymous user).
firebase.auth().currentUser.linkWithCredential(credential).then(function(user) {
  console.log("Anonymous account successfully upgraded", user);
}, function(error) {
  console.log("Error upgrading anonymous account", error);
});

Let me know if that works!

Sign up to request clarification or add additional context in comments.

5 Comments

firebase.User.prototype.link is deprecated. Please use firebase.User.prototype.linkWithCredential instead.
Thanks for this answer - the same logic applies in client mobile apps using Firebase. I was experiencing the same issue in an iOS app, and this logic fixed it. The Firebase docs on this aren't very clear - they should highlight this (if anyone from Google reads this).
Docs did not explain well at all that linkWithCredential is basically a replacement for createUserWithEmailAndPassword.
is currentUser is predefined?
Latest version is AuthCredential authCredential = EmailAuthProvider.getCredential(email: email, password: password);
3

After you log in as an Anonymous user, run this code to raise Popup and connect your anon user wit some OAUTH provider

const provider = new firebase.auth.FacebookAuthProvider()
firebase.auth().currentUser.linkWithPopup(provider)
console.log(provider)

Comments

0

For iOS, Swift 5 to create a credential use

EmailAuthProvider.credential(withEmail: , password: )

example:

let credential = EmailAuthProvider.credential(withEmail: emailTextField.text!, password: passwordTextField.text!)
        
Auth.auth().currentUser?.link(with: credential, completion: { (authDataResult: AuthDataResult?, error) in

    // ...
})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.