Migrating from Firebase Dynamic Links
Firebase Dynamic Links (FDL) shut down on August 25, 2025. Crisp is a drop-in resolver with the same link shape, deferred deep-link support, and one SDK call to swap. This guide takes you from a Firebase project to fully migrated in about 15 minutes.
page.link domain keeps working during the cutover.1. Install the SDK
Add the Crisp SDK to your project. React Native and Flutter ship first (thin clients — hashing is server-side); native iOS and Android follow the same surface.
npm install @crisp-to/react-native @react-native-async-storage/async-storage
dependencies: crisp_flutter: ^0.1.0
.package(url: "https://github.com/crisp-to/crisp-ios", from: "0.1.0")
implementation("to.crisp:crisp-android:0.1.0")
npm install @crisp-to/web # web SDK — coming in phase 2
2. Map your domain & import
In the Crisp dashboard, open Deep links → Firebase import, add your existing page.link domain, and upload the CSV you exported. Crisp remaps every short suffix, parameter, and fallback automatically.
3. Swap the resolver call
Replace your getDynamicLink / handleUniversalLink handler with the Crisp deferred-link handler. One callback covers both live links and post-install deferred matches, so your routing logic stays.
// Before — Firebase Dynamic Links // dynamicLinks().onLink(link => { ... }) import { CrispSDK } from "@crisp-to/react-native"; CrispSDK.initialize({ apiKey: "sdk_live_…", appId: "app_…" }); CrispSDK.onDeferredLink((link) => { router.navigate(link.shortCode, link.params); // fires for live AND deferred });
// Before — FirebaseDynamicLinks.instance.onLink.listen(...) import 'package:crisp_flutter/crisp_flutter.dart'; CrispSDK.initialize(const CrispOptions(apiKey: 'sdk_live_…', appId: 'app_…')); CrispSDK.onDeferredLink((link) { router.go(link.shortCode!, extra: link.params); // live AND deferred });
// Before — DynamicLinks.dynamicLinks().handleUniversalLink(url) { ... } import CrispSDK CrispSDK.shared.initialize(apiKey: "sdk_live_…", appId: "app_…") CrispSDK.shared.onDeferredLink { link in Router.handle(shortCode: link.shortCode, params: link.params) }
// Before — FirebaseDynamicLinks.getInstance()... CrispSDK.initialize(context, "sdk_live_…", "app_…") CrispSDK.onDeferredLink { link -> navController.navigate(link.shortCode, link.params) }
// Web SDK ships in phase 2 — same resolver surface. const link = await crisp.resolve(window.location.href) router.push(link.params.path)
4. Deferred deep links
When a user taps a link without the app installed, Crisp preserves the destination across the App Store / Play Store install. On first launch the SDK matches the install automatically — your onDeferredLink handler fires with link.deferred === true and the original params. No extra call needed.
Parameter reference
Every FDL query parameter maps to a Crisp field. The import does this automatically; the table is for links you build by hand.