You can pass state via a continue URL when sending email actions for password resets or verifying a user's email. This provides the user the ability to go back to the app after the action is completed. In addition, you can specify whether to handle the email action link directly from a mobile application when it is installed instead of a web page.
This can be extremely useful in the following common scenarios:
A user, not currently logged in, may be trying to access content that requires the user to be signed in. However, the user might have forgotten their password and therefore trigger the reset password flow. At the end of the flow, the user expects to go back to the section of the app they were trying to access.
An application may only offer access to verified accounts. For example, a newsletter may require the user to verify their email before subscribing. The user would go through the email verification flow and expect to go back to the app to complete their subscription.
In other cases, the user may have started the flow from their mobile device and expect after verification to return back to their mobile app instead of the browser.
Having the ability to pass state via a continue URL is a powerful feature that Firebase Auth provides and which can significantly enhance the user experience.
Passing state/continue URL in email actions
In order to securely pass a continue URL, the domain for the URL will need to be whitelisted in the Firebase console. This is done in the Authentication section by adding this domain to the list of Authorized domains under the Sign-in method tab if it is not already there.
An ActionCodeSettings instance needs to be provided when sending a password reset email or a verification email. It can be created with the associated ActionCodeSettings.Builder class which contains the following methods:
Method | Description |
---|---|
setUrl(String url) |
Sets the link (state/continue URL) which has different meanings in different contexts:
|
setIOSBundleId(String iOSBundleId) |
Sets the iOS bundle ID. This will try to open the link in an iOS app if it is installed. The iOS app needs to be registered in the Console. |
setAndroidPackageName(String androidPackageName, boolean installIfNotAvailable, String minimumVersion) |
Sets the Android package name. This will try to open the link in an
android app if it is installed. If installIfNotAvailable is set to true , it specifies
whether to install the Android app if the device supports it and the app
is not already installed. If minimumVersion is specified,
and an older version of the app is installed, the user is taken to the
Play Store to upgrade the app. The Android app needs to be registered in
the Console. |
setHandleCodeInApp(boolean status) |
Whether the email action link will be opened in a mobile app or a web link first. The default is false. When set to true, the action code link will be be sent as a Universal Link or Android App Link and will be opened by the app if installed. In the false case, the code will be sent to the web widget first and then on continue will redirect to the app if installed. |
setDynamicLinkDomain(String dynamicLinkDomain) |
Sets the dynamic link domain (or subdomain) to use for the current link if it is to be opened using Firebase Dynamic Links. As multiple dynamic link domains can be configured per project, this field provides the ability to explicitly choose one. If none is provided, the first domain is used by default. |
The following example illustrates how to send an email verification link that
will open in a mobile app first as a Firebase Dynamic Link
(iOS app com.example.ios
or Android app com.example.android
). The
deep link will contain the continue URL payload
https://www.example.com/?email=user@example.com
.
Kotlin+KTX
val auth = Firebase.auth val user = auth.currentUser!! val url = "http://www.example.com/verify?uid=" + user.uid val actionCodeSettings = ActionCodeSettings.newBuilder() .setUrl(url) .setIOSBundleId("com.example.ios") // The default for this is populated with the current android package name. .setAndroidPackageName("com.example.android", false, null) .build() user.sendEmailVerification(actionCodeSettings) .addOnCompleteListener { task -> if (task.isSuccessful) { Log.d(TAG, "Email sent.") } }
Java
FirebaseAuth auth = FirebaseAuth.getInstance(); FirebaseUser user = auth.getCurrentUser(); String url = "http://www.example.com/verify?uid=" + user.getUid(); ActionCodeSettings actionCodeSettings = ActionCodeSettings.newBuilder() .setUrl(url) .setIOSBundleId("com.example.ios") // The default for this is populated with the current android package name. .setAndroidPackageName("com.example.android", false, null) .build(); user.sendEmailVerification(actionCodeSettings) .addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { if (task.isSuccessful()) { Log.d(TAG, "Email sent."); } } });
Configuring Firebase Dynamic Links
Firebase Auth uses Firebase Dynamic Links when sending a link that is meant to be opened in a mobile application. In order to use this feature, Dynamic Links need to be configured in the Firebase Console.
Enable Firebase Dynamic Links:
- In the Firebase console, open the Dynamic Links section.
-
If you have not yet accepted the Dynamic Links terms and created a Dynamic Links domain, do so now.
If you already created a Dynamic Links domain, take note of it. A Dynamic Links domain typically looks like the following example:
example.page.link
You will need this value when you configure your Apple or Android app to intercept the incoming link.
Configuring Android applications:
- If you plan on handling these links from your Android application, the Android package name needs to be specified in the Firebase Console project settings. In addition, the SHA-1 and SHA-256 of the application certificate need to be provided.
- You will also need to configure the intent filter for the deep link in you AndroidManifest.xml file.
- For more on this, refer to Receiving Android Dynamic Links instructions.
Configuring iOS applications:
- If you plan on handling these links from your iOS application, the iOS bundle ID needs to be specified in the Firebase Console project settings. In addition, the App Store ID and the Apple Developer Team ID also need to be specified.
- You will also need to configure the FDL universal link domain as an Associated Domain in your application capabilities.
- If you plan to distribute your application to iOS versions 8 and under, you will need to set your iOS bundle ID as a custom scheme for incoming URLs.
- For more on this, refer to Receiving iOS Dynamic Links instructions.
Handling email actions in a web application
You can specify whether you want to handle the action code link from a web
application first and then redirect to another web page or mobile application
after successful completion, provided the mobile application is available.
This is done by calling setHandleCodeInApp(false)
in the
ActionCodeSettings.Builder
object. While an iOS bundle ID or Android package name are not required, providing them will allow the user
to redirect back to the specified app on email action code completion.
The web URL used here, is the one configured in the email action templates section. A default one is provisioned for all projects. Refer to customizing email handlers to learn more on how to customize the email action handler.
In this case, the link within the continueUrl
query parameter will be
an FDL link whose payload is the URL
specified in the ActionCodeSettings
object. While you can intercept and handle the incoming link from your app
without any additional dependency, we recommend using the FDL client library to
parse the deep link for you.
When handling email actions such as email verification, the action code from the
oobCode
query parameter needs to be parsed from the deep link and then applied
via applyActionCode
for the change to take effect, i.e. email to be verified.
Handling email actions in a mobile application
You can specify whether you want to handle the action code link within your
mobile application first, provided it is installed. With Android applications,
you also have the ability to specify via the installIfNotAvailable
boolean that the app
is to be installed if the device supports it and it is not already installed.
If the link is clicked from a device that does not support the mobile
application, it is opened from a web page instead.
This is done by calling setHandleCodeInApp(true)
in the
ActionCodeSettings.Builder
object. The mobile application's Android package name or iOS bundle ID will also need to be specified.
The fallback web URL used here, when no mobile app is available, is the one configured in the email action templates section. A default one is provisioned for all projects. Refer to customizing email handlers to learn more on how to customize the email action handler.
In this case, the mobile app link sent to the user will be an FDL link whose
payload is the action code URL, configured in the Console, with the query
parameters oobCode
, mode
, apiKey
and continueUrl
. The latter will be the
original URL
specified in the ActionCodeSettings
object. While you can
intercept and handle the incoming link from your app without any additional
dependency, we recommend using the FDL client library to parse the deep link for
you. The action code can be applied directly from a mobile application similar
to how it is handled from the web flow described in the
customizing email handlers section.
When handling email actions such as email verification, the action code from the
oobCode
query parameter needs to be parsed from the deep link and then applied
via applyActionCode
for the change to take effect, i.e. email to be verified.