Migrating Away from Firebase Dynamic Links in Flutter Before Shutdown
With Firebase Dynamic Links decommissioned, here is your definitive migration roadmap for deep linking in Flutter using App Links, Universal Links, and app_links.
Published on • October 30, 2026
AI Assistant

Google officially announced the sunset and decommissioning of Firebase Dynamic Links (FDL). For years, Flutter developers relied on FDL for referral links, passwordless email authentication, and marketing campaigns that preserved context through app store installation.
With FDL shutdown in effect, every Flutter app must migrate to standard, platform-native deep linking standards: Android App Links and Apple Universal Links, orchestrated through modern packages like app_links or routing libraries like GoRouter.
The Replacement Architecture
Firebase Dynamic Links relied on intermediate web redirects hosted by Google. The modern replacement leverages standard web domain verification:
- Android App Links: Verified via
https://<yourdomain>/.well-known/assetlinks.json - iOS Universal Links: Verified via
https://<yourdomain>/.well-known/apple-app-site-association - Flutter Router: Handled client-side using
app_linksor GoRouter.
User taps link (https://myapp.com/invite?code=123)
├── If App Installed: OS bypasses browser, opens Flutter app directly
└── If App Not Installed: Browser opens fallback web page with App Store buttons
Implementing Universal Deep Linking in Flutter
The community-recommended replacement for listening to incoming links is app_links:
dependencies:
app_links: ^6.3.0
Listening to Streamed Links
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:app_links/app_links.dart';
class DeepLinkManager {
static final DeepLinkManager instance = DeepLinkManager._internal();
DeepLinkManager._internal();
final _appLinks = AppLinks();
StreamSubscription<Uri>? _sub;
void initialize(BuildContext context) {
// Handle initial link if app opened via URL
_appLinks.getInitialLink().then((uri) {
if (uri != null) _handleNavigation(context, uri);
});
// Listen to incoming links while app is in foreground/background
_sub = _appLinks.uriLinkStream.listen((uri) {
_handleNavigation(context, uri);
});
}
void _handleNavigation(BuildContext context, Uri uri) {
if (uri.path == '/product') {
final id = uri.queryParameters['id'];
Navigator.of(context).pushNamed('/product', arguments: id);
}
}
void dispose() {
_sub?.cancel();
}
}
What About Deferred Deep Linking?
If your business strictly requires deferred deep linking (preserving promotional link parameters after an uninstalled user installs the app from the App Store), consider third-party mobile attribution providers (MAPs) like Adjust, AppsFlyer, or Branch.io, or host your own lightweight clipboard-based landing page bridge.