It's no news that, come August 25, 2025
, Firebase
will no longer support dynamic links
for Flutter applications. To that effect, we will need to handle the app link (for Android) and the universal link (for iOS) ourselves. And in this article, we will be doing so with the help of onGenerateRoute.
Table of Content
- ๐ Introduction
- โจ AppLink Overview
- โ๏ธ Updating AndroidManifest.xml
- ๐ฆ Creating SHA256
- ๐ช Creating & Hosting assetlinks.json file
- ๐งช Testing and Confirming assetlinks.json
- ๐ Deploy app to PlayStore internal testing
โ Confirm the link is auto verified in the device hardware app settings
๐ฎ๐พโโ๏ธ Adding capability
โ๏ธ Testing Via cmd xcrun
โ๏ธ OnGenerateRoute Setup and Routing to a dynamic page with data
๐ Introduction
Deep or dynamic linking is a great feature that Flutter offers in its application to enable a continuance in data consumption from a website to a mobile application.
For instance, say you have an e-commerce website with products to be sold or an online campaign website where users need to vote or be voted for. A user could share a link to that product/profile with another user, who then clicks on the link to be led to the website to continue their business. In a situation where you have both a website and a mobile app and you want the users to still continue their business through the mobile interface, that is where a deep or dynamic link comes in.
NB: In situations where the shared user does not have the app installed, they'd be redirected to their respective device's stores (Play or Apple Store) to download and continue with the application.
PS: In this article, we will be handling the applink
and universal link
for Android and iOS, respectively.
โจ AppLink Overview
We will be following the official Android Guidelines.
โ๏ธ Updating AndroidManifest.xml
Navigate to your AndroidManifest.xml
file and add the below intent inside your <android>
block.
<meta-data android:name="flutter_deeplinking_enabled" android:value="true" />
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
<data android:scheme="http" />
<data android:host="gikwegbu.com" />
<data android:host="www.gikwegbu.com" />
</intent-filter>
NB: You need `flutter_deeplinking_enabled` for it to work; that way, the route can be passed from the Android routing system into our Flutter application.
NB: Please update the `gikwegbu` host with your personal domain name.
๐ฆ Creating SHA256
We will need to create an SHA256
for our application. To do that, open your root
project in the terminal
and run the below code:
keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android
Then copy the SHA256
value that comes up.
๐ช Creating & Hosting AssetLink.json file
You can either use the Statement List Generator and Tester link to Generate your statement
and in future, Test your statement
. Or simply update the below json file with your own details;
NB: This code MUST
be saved in the assetLinks.json
file.
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.gikwegbu.app",
"sha256_cert_fingerprints":
["PASTE YOUR OWN SHA256 HERE"]
}
}]
NB: Update the package_name
with your app's own.
Congratulations if you've gotten to this place so far; you're a genius. But before we host our json
file, we need to do something first. I assume you already have a PlayStore
account and an APP
created for your currently built application. If you don't, please pause and do so.
There is every tendency that your app already exists in the store, and you just want to include this feature, which is perfect. All I need you to do is get the SHA256
google Auto-created for you application in the integrity
section of the console and update the sha256_cert_fingerprints
in your AssetLink.json
. Remember, it's an array of SHA256
values, so just a comma
and the new SHA256
value from PlayStore console
.
[{
"relation":
["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.gikwegbu.app",
"sha256_cert_fingerprints":
["PASTE YOUR OWN SHA256 HERE", "PASTE GOOGLE PLAY CONSOLE SHA256 HERE TOO"]
}
}]
Hosting your AssetLink.json file;
For this, you will have to reach out to the person managing the website, as we need to upload our file to a specific directory.
http://gikwegbu.com/.well-known/assetlinks.json
NB: It is very important that you place assetlinks.json
inside the .well-known/
directory.
NB: The domain must match what you provided in your AndroidManifest.xml
android:host
data as well.
NB: Once it has been hosted, make sure it's accessible by visiting http://gikwegbu.com/.well-known/assetlinks.json
. If it's accessible, you'll see the json
data displayed.
๐งช Testing and Confirming AssetLink.json file
To test if your assetlink.json
will be OK, provide the required details in the Statement List Generator and Tester, then click on Test Statement
to confirm.
This will crawl your website, to confirm the assetlink.json
file is present, and the SHA256
keys are also valid.
As a bonus, try inputing the SHA256
you got from the Google Play Console
, to confirm it works too.
๐ Deploy app to PlayStore internal testing
Based on my earlier assumption that you just created the app on your Google Console
, we would be deploying to internal testing
, just so we could test out our deep links
before releasing them to the actual store.
NB: This article won't cover how to build and upload your appbundle
to the store.
PS: If you have already released your app, no problem, just continue with the next step.
On your Google Play Console
, go to the Deep Links
on Side Navigation
, If everything we've done so far has worked out well, you should get a pretty dashboard like below.
NB: If there's still an issue, please reach out to me, and I'll be glad to help out.
NB: Once you have uploaded the appbundle
to your internal testing, wait for a while (say an hour; honestly, I don't know how long it takes for Google to verify your assetlink and web domains) before installing it.
NB: When you have installed it on your device, go to your flutter app's
details, select Set as default
, > Supported web addresses
and see if the host
you provided in the AndroidManifest.xml
is/are present there.
โ Confirm the link is auto verified in the device hardware app settings
Because in our AndroidManifest.xml
, we set the <intent-filter android:autoVerify="true">
, therefore, you shouldn't see the toggle/switch
button beside your host
.
Approved Hosts
Whoop Whoooop!!!! We just finished Applink on our Android.
PS: Stick around to the end of the article to learn how the routing works with the onGenerateRoute
configs in Flutter
.
๐ Universal Link Overview
For our iOS application, we will be using a Universal link
, which is an exclusive type of deep link to Apple devices that uses either the http
or the https
schemes.
๐ฎ๐พโโ๏ธ Adding capability
In the next few steps, we will be working closely with XCode
via the following steps:
- Open your project in
XCode
, - In your
Project Navigator
, click on theRunner
. - Click the
Runner
in theTARGETS
section. - Select
Signing & Capabilities
. - Click on the
+ Capability
, - When the
Modal
pops up, search forAssociated Domains
and add it.
After adding the Associated Domains
, update the current web credential
Domains
with;
applinks:gikwegbu.com // first input
applinks:www.gikwegbu.com // second input
NB: I like adding more options so my app will be recognized when users try to access it with or without the www
.
NB: While the above is the easiest and UI approach of adding the Runner.entitlements
to your app, you could just create. a Runner.entitlements
file within your ios/Runner/
directory, ad add the below code manually:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:gikwegbu.com</string>
<string>applinks:www.gikwegbu.com</string>
</array>
</dict>
</plist>
NB: gikwegbu.com
should be your own domain
.
From our Step 3
above, whilst still on the Runner
in the TARGET
section:
- Click on the
info
tab. - Open the
URL Types
dropdown and complete the form with below data:
identifier
: your app's bundle Identifier,
URL Schemes
: https.
NB: You can get you bundle Identifier
from your Signing & Capabilities
tab in XCode
.
NB: For the iOS routing system to successfully parse the dynamic url back into our Flutter application, we need to add the below data into our info.plist file;
<key>FlutterDeepLinkingEnabled</key>
<true/>
๐ก Creating & Hosting AASA file
Open your project root
in the terminal
and run the below code:
$ touch apple-app-site-association
Then copy and paste the below code, with your own data
;
{
"applinks": {
"apps": [],
"details": [{
"appID": "[TEAM_ID].[APP_BUNDLE_ID]",
"paths": ["[PATH_FOR_REDIRECTION]"]
}]
}
}
NB: To get your Team_ID
, just open your apple dev account, you'd see the ID by the top right
, underneath your name
of your screen,
"paths": [
"/your_path", // Users will be be redirected if they visit <https://gikwegbu.com/your_path>
"/your_path/*", // Users will be redirected if they visit <https://gikwegbu.com/your_path/[shduewjakssd]>
"*", // will be redirected to any link <https://gikwegbu.com/[wild card links]>
"NOT /your_path", // Users will be be redirected to any link other than <https://gikwegbu.com/your_path>
"NOT /your_path/*", // Users be redirected to any link other than <https://gikwegbu.com/your_path/[wild card]>
]
Once you're done with the above, host the AASA file on your domain, within the .well-known/
directory, just like you did with your Android
assetlinks.json
file.
๐ Confirming Our AASA file
To confirm if the AASA file was properly hosted, once you visit the http://gikwegbu.com/.well-known/apple-app-site-association
, the file will automatically be downloaded onto your machine.
NB: gikwegbu
will be your own domain.
โ๏ธ Testing Via cmd xcrun
First make sure your XCode
is running your Flutter app
, Open your terminal
and run the below code:
$ xcrun simctl openurl booted https://gikwegbu.com/guest/dsewe
NB: Since we haven't worked on the Routing system in our Flutter app, the above command should simply launch your app.
โ๏ธ OnGenerateRoute Setup and Routing to a dynamic page with data
For an efficient and cleaner codebase, I like to keep all my routes in a separate file.
Within your MaterialApp
, in your main.dart
file, you can add your onGenerateRoute
data and point it to the external routes
file.
Image of the main.dart file
Here, we will create a class called Routes
;
class Routes {
static Route<dynamic> generateRoute(RouteSettings settings) {
debugPrint('${settings.name} Is the current route' );
if (settings.name!.contains('guest')) {
final page = PreInviteInfoScreen(
code: settings.name!.split('/').last,
);
return MaterialPageRoute(builder: (_) => page);
}
final args = settings.arguments; // For screens that requires arguements to be passed
switch (settings.name) {
case HomeView.routeName:
const page = HomeView();
return MaterialPageRoute(builder: (_) => page);
default:
const page = HomeView();
return MaterialPageRoute(builder: (_) => page);
}
}
}
NB: For more context, say the link our users clicks on is https://www.gikwegbu.com/guest/Uhdys
, the if statement
, will check if that route has the guest
keyword, then extract to get the code as it a URL PATH
.
This way, when a user clicks on the link above, only the Uhdys
is now being passed as the argument
for the next screen immediately the app launches.
THE END
So with the above sets of instructions and examples, you should be able to get the Applink and Universal link ready for your FLutter application. CONGRATULATIONS AND GOOD LUCK.
Top comments (1)
This was super helpful... Thank you.