Skip to content
Blog

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:

  1. Android App Links: Verified via https://<yourdomain>/.well-known/assetlinks.json
  2. iOS Universal Links: Verified via https://<yourdomain>/.well-known/apple-app-site-association
  3. Flutter Router: Handled client-side using app_links or 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
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.