How to Migrate from Firebase Dynamic Links to Flutter Deep Linking
Firebase Dynamic Links shut down on August 25, 2025. If your Flutter app still has firebase_dynamic_links in pubspec.yaml, your deep links are broken for every user right now. This guide walks you through a complete migration to Flinku in under 30 minutes.
What You Are Replacing
Firebase Dynamic Links handled three things in your Flutter app:
Getting the initial link on a cold start — getInitialLink()
Listening for links while the app is running — onLink stream
Creating new links programmatically — buildShortLink()
Flinku replaces all three with a simpler API and no Firebase dependency.
Step 1 — Create Your Flinku Project
Sign up at app.flinku.dev — free, no credit card required.
Click "New Project" and fill in your app details:
Your iOS Bundle ID (e.g. com.yourcompany.yourapp)
Your Android Package Name (e.g. com.yourcompany.yourapp)
Your App Store URL and Play Store URL
Flinku will provision your subdomain automatically: yourapp.flku.dev
Keep the dashboard open — you will need your publishable key in Step 3.
Step 2 — Configure iOS Universal Links
In your Firebase setup you had an apple-app-site-association file. Flinku serves this automatically at https://yourapp.flku.dev/.well-known/apple-app-site-association — no manual file management needed.
In your Xcode project, open Runner.entitlements and update your associated domains:
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:yourapp.flku.dev</string>
</array>
Remove the old Firebase domain entry if it is still there.
Step 3 — Configure Android App Links
Flinku serves assetlinks.json automatically at https://yourapp.flku.dev/.well-known/assetlinks.json.
In android/app/src/main/AndroidManifest.xml, add an intent filter for your Flinku subdomain:
<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" android:host="yourapp.flku.dev" />
</intent-filter>
Step 4 — Update pubspec.yaml
Remove the Firebase dependency and add Flinku:
dependencies:
# Remove this:
# firebase_dynamic_links: ^x.x.x
# Add this:
flinku_sdk: ^latest
# Check current version at pub.dev/packages/flinku_sdk
Run flutter pub get.
Step 5 — Replace the SDK Code
Initialization
// Before (Firebase)
await Firebase.initializeApp();
// After (Flinku) — add to main() before runApp()
await Flinku.configure(
subdomain: 'yourapp',
apiKey: 'flk_pk_your_publishable_key',
);
Handling the Initial Deep Link
// Before (Firebase)
final PendingDynamicLinkData? initialLink =
await FirebaseDynamicLinks.instance.getInitialLink();
if (initialLink != null) {
final Uri deepLink = initialLink.link;
navigateTo(deepLink.path);
}
// After (Flinku)
final match = await Flinku.match();
if (match != null) {
navigateTo(match.deepLink, params: match.params);
}
Listening for Links While the App Is Running
// Before (Firebase)
FirebaseDynamicLinks.instance.onLink.listen((dynamicLinkData) {
navigateTo(dynamicLinkData.link.path);
});
// After (Flinku)
// Flinku.match() handles both cold start and foreground links.
// Use your existing app_links or uni_links setup for foreground
// Universal Link handling — Flinku match() is for deferred linking only.
Creating Links Programmatically
// Before (Firebase)
final dynamicLinkParams = DynamicLinkParameters(
link: Uri.parse('https://yourapp.com/product/123'),
uriPrefix: 'https://yourapp.page.link',
androidParameters: AndroidParameters(packageName: 'com.yourcompany.app'),
iosParameters: IOSParameters(bundleId: 'com.yourcompany.app'),
);
final shortLink = await FirebaseDynamicLinks.instance.buildShortLink(dynamicLinkParams);
// After (Flinku)
final link = await Flinku.createLink(
name: 'Product 123',
deepLink: 'yourapp://product/123',
title: 'Check out this product',
);
For instant link creation with no UI delay, use createLinkInstant:
// Generates the slug on-device instantly, syncs to server in background
final link = Flinku.createLinkInstant(
name: 'Product 123',
deepLink: 'yourapp://product/123',
);
// link.shortUrl is available immediately — no await, no spinner
Step 6 — Migrate Your Existing Links
If you have existing Firebase Dynamic Links you want to preserve, use the Flinku Migration Tool:
Export your links from the Firebase Console Paste them into the migration tool Select your project Click "Convert All Links"
All your existing links are converted to Flinku links in one step.
Step 7 — Test Before Releasing
Use the free Deep Link Tester to verify your links are routing correctly before you release the app update.
Test the full deferred deep linking flow:
Install the app on a test device Tap a Flinku link from a browser or Messages app Verify it opens the correct screen Uninstall the app, tap the same link, install from the App Store, open the app — it should still route to the correct screen
Common Issues After Migration
Link opens browser instead of app — your associated domains entitlement is missing or the domain is not matching. Use the AASA Validator to check.
match() always returns null — confirm your subdomain in configure() matches exactly what is shown in your Flinku project settings. Check that your Bundle ID and Team ID are entered correctly in the project.
App not found on App Store lookup — if your app is only published in specific regions, verify the country code in your project settings matches a region where your app is indexed.
That Is It
The full migration typically takes under 30 minutes. Your existing Firebase Dynamic Links are broken today — Flinku has you back up and running before your next deploy.