Nolence
Nolence

Reputation: 2254

Update a Firebase anonymous user using Email & Password

People can sign into my app anonymously:

FirebaseAuth.instance.signInAnonymously();

Once inside, they have a little indicator that reminds them if they want be able to save their data across phones, they'll need to sign in. For Google authentication that looks like this:

Future<void> anonymousGoogleLink() async {
  try {
    final user = await auth.currentUser();
    final credential = await googleCredential();

    await user.linkWithCredential(credential);
  } catch (error) {
    throw _errorToHumanReadable(error.toString());
  }
}

where googleCredential is:


Future<AuthCredential> googleCredential() async {
  final googleUser = await _googleSignIn.signIn();

  if (googleUser == null) throw 'User Canceled Permissions';

  final googleAuth = await googleUser.authentication;
  final signInMethods = await auth.fetchSignInMethodsForEmail(
    email: googleUser.email,
  );

  if (signInMethods.isNotEmpty && !signInMethods.contains('google.com')) {
    throw 'An account already exists with the same email address but different sign-in credentials. Sign in using a provider associated with this email address.';
  }

  return GoogleAuthProvider.getCredential(
    accessToken: googleAuth.accessToken,
    idToken: googleAuth.idToken,
  );
}

Now I'd like to do the same thing but instead link the current anonymous account with email and password authentication.

EDIT:

Found a possible solution while writing this. Leaving for others to possibly see. Feel free to correct me.

Upvotes: 2

Views: 1542

Answers (1)

Nolence
Nolence

Reputation: 2254

On the FirebaseUser object the method updatePassword has this doc string:

/// Updates the password of the user.
///
/// Anonymous users who update both their email and password will no
/// longer be anonymous. They will be able to log in with these credentials.
/// ...

You should just be able to update both and then they'll be authenticated as a regular user. For me that looked like:

Future<void> anonymousEmailLink({
  @required FirebaseUser user,
  @required String email,
  @required String password,
}) async {
  try {
    await Future.wait([
      user.updateEmail(email),
      user.updatePassword(password),
    ]);
  } catch (error) {
    throw _errorToHumanReadable(error.toString());
  }
}

Upvotes: 4

Related Questions