Why should you migrate from Firebase Dynamic Links to another solution? The straightforward answer is: ‘Firebase Dynamic Links is deprecated and should not be adopted in new projects. The service will shut down on August 25, 2025.
I personally used Firebase Dynamic Links in a Flutter app, and the transition was smoother than I expected. I considered several other approaches, like Branch, AppsFlyer, Bitly, and many more third-party packages, which could have been the best options for my cross-platform app. However, I decided to go the native route using App Links, which is more cost-efficient. In this tutorial, I will guide you through setting up App Links in your Flutter app, which is quite similar for any other framework.
In this article, we will explore the native approach to setting up App Links in your Flutter app
Android App Links Setup Steps
- Step One: Open your
AndroidManifest.xml
file and add an intent filter like this. Let's assume your website is "www.myapp.com":
2. Step Two: On the server side, create a file called assetlinks.json
in the following format:
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.example",
"sha256_cert_fingerprints":
["14:6D:E9:83:C5:73:06:50:D8:EE:B9:95:2F:34:FC:64:16:A0:83:42:E6:1D:BE:A8:8A:04:96:B2:3F:CF:44:E5"]
}
}]
You need your SHA-256 key and package name. You can generate the SHA-256 key by navigating to the android
directory and running ./gradlew signingReport
. The package name is the application ID declared in the app's build.gradle
file.
3. Finally, upload your assetlinks.json
file to declare the association between your website and your intent filters by hosting the Digital Asset Links JSON file at the following location:
https://www.myapp.com/.well-known/assetlinks.json
Confirm the proper configuration of your Digital Asset Links JSON file on this platform
ios app links set up steps
- Open your project in Xcode and click on “Runner” under “Targets”.
- Click the add button, search for “Associated Domains”, and add the links in this format. If you were previously using Firebase Dynamic Links, you might see an existing link — just add the new one.
3.Navigate to “Runner,” click on “Info,” and add a new key called FlutterDeepLinkingEnabled
. Set its type to Boolean and its value to Yes.
4. Now, you need to create an apple-app-site-association
file. You don't need to add .json
at the end of the file; all you need is <Application Identifier Prefix>.<Bundle Identifier>
.
"applinks": {
"apps": [],
"details": [
{
"appID": "K3453134.com.example",
"paths": [
"*"
]
}
]
}
}
After you construct the association file, place it in your site’s .well-known
directory. The file’s URL should match the following format:
https://www.myapp.com/.well-known/apple-app-site-association
Now that you’ve completed the native implementation, congratulations! 🥂 Let’s dive straight into our Flutter code. Add the applinks
package from pub.dev and create a class (you can choose the name). You can listen for cold and warm links in each function as needed.
Also, initialize this in your app root by calling init
and initDeepLinks
in your main
or App
widget (for example, app.dart
):
final DeepLinkService _appDeepLink = DeepLinkService.instance;
Finally, assuming you are familiar with how linking works in the app, but just in case you are new to this: for a link like https://www.myapp.com/offers/987487763725292, it will navigate directly to the offer page and fetch the particular offer by its unique ID.
void _handleWarmDeeepLink(Uri uriValue, BuildContext context) {
// Handle link when app is in warm state (front or background)
var isOffer = uriValue.path.contains("offers");
var isTrade = uriValue.path.contains("trades");
var isReferral = uriValue.path.contains("signup");
if (isOffer) {
String offerId = uriValue.pathSegments.last;
LoginNavModel loginNavModel = LoginNavModel(offerId: offerId);
final is_used = locator<LocalCache>().getFromLocalCache(
AppStrings.is_app_used_pref_key,
);
if (is_used == true) {
locator<NavigationHandler>().pushNamed(Routes.art_details_view, arg: {
"id": loginNavModel.offerId,
"fromDynamic": true,
});
} else {
_navigateToLogin(loginNavModel);
}
}
Also, regarding meta-tags like Firebase, I assume your app has a web presence or at least a web counterpart. These can be configured from there with minimal research.
Thank you for reading. As you continue your migration journey, remember that I’m here to assist you with any questions or issues that may arise. For meta-tagging, like setting up Firebase, your app should ideally have a web interface, which can be configured with a bit of research.