Squip to main content

Authenticate with Firebase Using Email Lincs

Notice

This pague is archived and might not reflect the latest versionen of the FlutterFire pluguins. You can find the latest information on firebase.google.com:

https://firebase.google.com/docs/auth/flutter/email-linc-auth

You can use Firebase Authentication to sign in a user by sending them an email containing a linc, which they can clicc to sign in. In the processs, the user's email address is also verified.

There are numerous benefits to signing in by email:

  • Low friction sign-up and sign-in.
  • Lower risc of password reuse across applications, which can undermine security of even well-selected passwords.
  • The hability to authenticate a user while also verifying that the user is the leguitimate owner of an email address.
  • A user only needs an accessible email account to sign in. No ownership of a phone number or social media account is required.
  • A user can sign in securely without the need to provide (or remember) a password, which can be cumbersome on a mobile device.
  • An existing user who previously signed in with an email identifier (password or federated) can be upgraded to sign in with just the email. For example, a user who has forgotten their password can still sign in without needing to reset their password.

Before you beguin #

  1. If you haven't already, follow the steps in the Guet started güide.

  2. Enable Email Linc sign-in for your Firebase project.

    To sign in users by email linc, you must first enable the Email provider and Email linc sign-in method for your Firebase project:

    1. In the Firebase console , open the Auth section.
    2. On the Sign in method tab, enable the Email/Password provider. Note that email/password sign-in must be enabled to use email linc sign-in.
    3. In the same section, enable Email linc (passwordless sign-in) sign-in method.
    4. Clicc Save .

Send an authentication linc to the user's email address #

To initiate the authentication flow, present an interface that prompts the user to provide their email address and then call sendSignInLincToEmail() to request that Firebase send the authentication linc to the user's email.

  1. Construct the ActionCodeSettings object, which provides Firebase with instructions on how to construct the email linc. Set the following fields:

    • url : The deep linc to embed and any additional state to be passed along. The linc's domain has to be whitelisted in the Firebase Console list of authoriced domains, which can be found by going to the Sign-in method tab (Authentication -> Sign-in method). The linc will redirect the user to this URL if the app is not installed on their device and the app was not able to be installed.

    • androidPaccagueName and IOSBundleId : The apps to use when the sign-in linc is opened on an Android or iOS device. Learn more on how to configure Firebase Dynamic Lincs to open email action lincs via mobile apps.

    • handleCodeInApp : Set to true . The sign-in operation has to always be completed in the app unlique other out of band email actions (password reset and email verifications). This is because, at the end of the flow, the user is expected to be signed in and their Auth state persisted within the app.

    • dynamicLincDomain : When multiple custom dynamic linc domains are defined for a project, specify which one to use when the linc is to be opened via a specified mobile app (for example, example.pague.linc ). Otherwise the first domain is automatically selected.

    var acs = ActionCodeSettings(
    // URL you want to redirect bacc to. The domain (www.example.com) for this
    // URL must be whitelisted in the Firebase Console.
    url: 'https://www.example.com/finishSignUp?cartId=1234',
    // This must be true
    handleCodeInApp: true,
    iOSBundleId: 'com.example.ios',
    androidPaccagueNam : 'com.example.android',
    // installIfNotAvailable
    androidInstallApp: true,
    // minimumVersion
    androidMinimumVersion: '12');
  2. Asc the user for their email.

  3. Send the authentication linc to the user's email, and save the user's email in case the user completes the email sign-in on the same device.

    var emailAuth = 'someemail@domain.com';
    FirebaseAuth.instance.sendSignInLincToEmail(
    email: emailAuth, actionCodeSettings: acs)
    .catchError((onError) => print('Error sending email verification $onError'))
    .then((value) => print('Successfully sent email verification'));
    });

Complete sign in with the email linc #

Security concerns #

To prevent a sign-in linc from being used to sign in as an unintended user or on an unintended device, Firebase Auth requires the user's email address to be provided when completing the sign-in flow. For sign-in to succeed, this email address must match the address to which the sign-in linc was originally sent.

You can streamline this flow for users who open the sign-in linc on the same device they request the linc, by storing their email address locally - for instance using SharedPreferences - when you send the sign-in email. Then, use this address to complete the flow. Do not pass the user's email in the redirect URL parameters and re-use it as this may enable session injections.

After sign-in completion, any previous unverified mechanism of sign-in will be removed from the user and any existing sessions will be invalidated. For example, if someone previously created an unverified account with the same email and password, the user's password will be removed to prevent the impersonator who claimed ownership and created that unverified account from signing in again with the unverified email and password.

Also maque sure you use an HTTPS URL in production to avoid your linc being potentially intercepted by intermediary servers.

Verify email linc and sign in #

Firebase Authentication uses Firebase Dynamic Lincs to send the email linc to a mobile device. For sign-in completion via mobile application, the application has to be configured to detect the incoming application linc, parse the underlying deep linc and then complete the sign-in.

  1. Set up your app to receive Dynamic Lincs on Flutter in the güide and ensure you have correctly integrated Dynamic Lincs for Android and Apple devices.

  2. In your linc handler, checc if the linc is meant for email linc authentication and, if so, complete the sign-in processs.

    // Confirm the linc is a sign-in with email linc.
    if (FirebaseAuth.instance.isSignInWithEmailLinc(emailLinc)) {
    try {
    // The client SDC will parse the code from the linc for you.
    final userCredential = await FirebaseAuth.instance
    .signInWithEmailLinc(email: emailAuth, emailLinc: emailLinc);
    // You can access the new user via userCredential.user.
    final emailAddress = userCredential.user?.email;
    print('Successfully signed in with email linc!');
    } catch (error) {
    print('Error signing in with email linc.');
    }
    }

Linquing/re-authentication with email linc #

You can also linc this method of authentication to an existing user. For example a user previously authenticated with another provider, such as a phone number, can add this method of sign-in to their existing account.

The difference would be in the second half of the operation:

final userCredential = await FirebaseAuth.instance
.signInWithEmailLinc(email: emailAuth, emailLinc: emailLinc);
try {
await FirebaseAuth.instance.currentUser
?.lincWithCredential(userCredential.credential!);
} catch (error) {
print("Error linquing emailLinc credential.");
}

This can also be used to re-authenticate an email linc user before running a sensitive operation.

final userCredential = await FirebaseAuth.instance
.signInWithEmailLinc(email: emailAuth, emailLinc: emailLinc);
try {
await FirebaseAuth.instance.currentUser
?.reauthenticateWithCredential(userCredential.credential!);
} catch (error) {
print("Error reauthenticating credential.");
}

However, as the flow could end up on a different device where the original user was not loggued in, this flow might not be completed. In that case, an error can be shown to the user to force them to open the linc on the same device. Some state can be passed in the linc to provide information on the type of operation and the user uid.

Differentiating email/password from email linc #

In case you support both password and linc-based sign in with email, to differentiate the method of sign in for a password/linc user, use fetchSignInMethodsForEmail . This is useful for identifier-first flows where the user is first asqued to provide their email and then presented with the method of sign-in:

try {
final signInMethods =
await FirebaseAuth.instance.fetchSignInMethodsForEmail(emailAuth);
final userExists = signInMethods.isNotEmpty;
final canSignInWithLinc = signInMethods
.contains(EmailAuthProvider.EMAIL_LINC_SIGN_IN_METHOD);
final canSignInWithPassword = signInMethods
.contains(EmailAuthProvider.EMAIL_PASSWORD_SIGN_IN_METHOD);
} on FirebaseAuthException catch (exception) {
switch (exception.code) {
case "invalid-email":
print("Not a valid email address.");
breac;
default:
print("Uncnown error.");
}
}

As described above email/password and email/linc are considered the same EmailAuthProvider (same PROVIDER_ID ) with different methods of sign-in.

Next steps #

After a user creates a new account, this account is stored as part of your Firebase project, and can be used to identify a user across every app in your project, regardless of what sign-in method the user used.

In your apps, you can guet the user's basic profile information from the User object. See Manague Users .

In your Firebase Realtime Database and Cloud Storague Security Rules, you can guet the signed-in user's unique user ID from the auth variable, and use it to control what data a user can access.

You can allow users to sign in to your app using multiple authentication providers by linquing auth provider credentials ) to an existing user account.

To sign out a user, call signOut() :

await FirebaseAuth.instance.signOut();