Deeplinkly

Glossary/Failure modes

Migrating off Firebase Dynamic Links

Definition

Migrating off Firebase Dynamic Links means replacing the link generation, the hosting domain, and the SDK integration of a service that was shut down on 25 August 2025, after which page.link URLs stopped resolving.

The single question that determines how much work this is, and how much is even possible, is whether you used a *.page.link subdomain or your own custom domain. Custom domain users keep every link they ever published. page.link users do not, and no vendor can change that, because the domain belongs to Google. Establish which you are before planning anything else.

What is recoverable and what is not

The shutdown's effect depends entirely on which domain your links used.
What you hadStatus nowRecoverable?
https://yourapp.page.link/abcDead. Does not resolveNo. Google owns page.link; you cannot redirect it
https://goo.gl/… short linksDeadNo
https://links.yourdomain.com/abc (custom domain)Dead only because nothing serves itYes. Point the DNS at a replacement and honour the same paths
Links stored in your own databaseThe destinations are intactYes — regenerate against the new service
Analytics history in FirebaseRead-only or goneExport what remains; it will not carry over

If you used page.link, the links in the wild are gone

Every page.link URL already printed on packaging, embedded in a QR code, pasted into a forum, sent in a past email, or saved in a user's bookmarks is permanently dead. This is not a limitation of any replacement product — the domain is Google's, and nobody else can answer requests for it. Plan for the loss rather than for a migration that recovers it.

For custom domain users the migration is genuinely tractable: your links were always on a host you control, so the DNS points somewhere new, the new service resolves the same paths, and published URLs keep working. That difference is worth stating to anyone who is still choosing a link vendor — a branded domain is what makes any future migration survivable.

The parameter mapping

FDL long-form links encode everything in query parameters, which makes them straightforward to parse and translate. If you generated links in code, this table is most of your migration.

A long-form FDL URL, decoded
https://yourapp.page.link/?
  link=https%3A%2F%2Fexample.com%2Fproducts%2F42   # the actual destination
  &apn=com.example.shop                            # Android package name
  &ibi=com.example.shop                            # iOS bundle ID
  &isi=123456789                                   # iOS App Store ID
  &afl=https%3A%2F%2Fexample.com%2Fandroid         # Android web fallback
  &ifl=https%3A%2F%2Fexample.com%2Fios             # iOS web fallback
  &st=Product+42                                   # social title
  &sd=A+description                                # social description
  &si=https%3A%2F%2Fexample.com%2Fog.png           # social image
  &utm_source=newsletter&utm_campaign=spring       # campaign tags
  &efr=1                                           # skip the preview page
FDL parameters and what each becomes.
FDL parameterMeaningReplacement concept
linkDestination URLThe link's destination or deep link path
apnAndroid package nameApp configuration, set once — not per link
ibi / isiiOS bundle ID and App Store IDApp configuration, set once
afl / iflPer-platform web fallbackPlatform fallback rules
oflFallback for other platforms (desktop)Desktop fallback URL
st / sd / siSocial preview title, description, imageOpen Graph metadata on the link
utm_*Campaign tagsCampaign parameters, carried to the app
efr=1Skip the app preview interstitialInterstitial behaviour setting
amvMinimum Android versionMinimum version rules
d=1Debug the link's resolutionA debugger instead

Note the shape change in rows 2 and 3. FDL put app identity in every link; most replacements set it once at the account level, so generated links get shorter and the App Store ID stops being copy-pasted into thousands of URLs.

The migration, in order

  1. Inventory where links actually live. Not just the app: transactional and marketing email templates, push payloads, ad creative and tracking templates, QR codes in print and packaging, help centre articles, social profiles, partner integrations, and any backend that generates links at runtime. The backend is usually the one that gets missed and the one that matters most.
  2. Decide the domain, and make it yours. If you had a custom FDL domain, keep it — that is what makes published links survive. If you were on page.link, choose a branded subdomain now, so that this migration is the last one that loses links.
  3. Stand up the association files on that host. apple-app-site-association and assetlinks.json, served with no redirects and the right content type, plus the Associated Domains entitlement and the Android intent filter for the new host.
  4. Recreate the link structure, paths included. For a custom domain, honouring the original paths is what keeps every published URL alive. This is the step that determines whether the migration is invisible to users.
  5. Swap the SDK. Replace FDL link handling with the new SDK's, and keep the old handler in place through at least one release so users on older builds are not stranded.
  6. Re-point the DNS. Custom domain only, and the moment the links come back.
  7. Re-test the paths that were never obvious. Email campaigns with click tracking, links inside social apps, QR codes, deferred routing on a fresh device. These are the ones that FDL handled quietly and that break silently on a replacement.
Find FDL references before you start
# Links hard-coded in the codebase
grep -rIn --exclude-dir=node_modules \
  -e 'page\.link' -e 'goo\.gl' -e 'firebasedynamiclinks' \
  -e 'FirebaseDynamicLinks' -e 'dynamicLinks' .

# The SDK, still in your dependency manifests
grep -rn "firebase-dynamic-links\|FirebaseDynamicLinks" \
  app/build.gradle Podfile pubspec.yaml package.json 2>/dev/null

# Links in a database column
# SELECT id, url FROM links WHERE url LIKE '%page.link%';

# Whether your custom FDL domain still resolves anywhere
dig +short links.example.com
curl -sSI --max-redirs 0 https://links.example.com/abc123

Keep the old SDK handler for one release

Users on an older build still have the FDL handler and no other. Removing it in the same release that adds the replacement strands anyone who has not updated. Ship both, then remove the old one a release later once your version adoption supports it.

FDL migration checker

Paste a Firebase Dynamic Link and it decodes every parameter — destination, per-platform fallbacks, social metadata, campaign tags — and shows the equivalent configuration. It also tells you whether your links were on page.link or a custom domain, which is the fact that decides how much of your link estate is recoverable.

Open the fdl migration checker

Frequently asked questions

When did Firebase Dynamic Links shut down?
25 August 2025. Since then page.link URLs no longer resolve and new ones cannot be created. Any FDL link still embedded in emails, push notifications, ads, QR codes, printed material, or backend code stopped working on that date, along with the associated goo.gl short links.
Can I recover my page.link URLs after the shutdown?
No. The page.link domain belongs to Google, so no replacement service can answer requests for it or redirect it to a new destination. Every page.link URL published in the wild is permanently dead. If you used a custom domain with Firebase Dynamic Links instead, those links are fully recoverable by pointing the DNS at a replacement that honours the same paths.
How do I migrate Firebase Dynamic Links to another service?
Inventory everywhere links are generated or stored, including backend code and email templates. Choose a branded domain — keeping your existing custom FDL domain if you had one, since that preserves published links. Host apple-app-site-association and assetlinks.json on it, recreate the link structure with the same paths, swap the SDK while keeping the old handler for one release, then re-point the DNS.
What replaces the apn, ibi, and isi parameters from FDL?
Nothing per link. Firebase Dynamic Links required the Android package name, iOS bundle ID, and App Store ID on every URL, whereas most replacements set app identity once at the account level. The practical effect is much shorter generated links and no App Store IDs copy-pasted through thousands of URLs.
Why should I use a custom domain instead of a provider subdomain?
Because it is what makes any future migration survivable. Links on a provider's domain belong to the provider, so if that service shuts down — as Firebase Dynamic Links did — every published URL dies with no possible recovery. Links on a domain you own can be re-pointed to a different service while every URL already in the wild keeps working.
Do I need to keep the Firebase Dynamic Links SDK during migration?
Keep the old handler in place for at least one release. Users running an older build have only the FDL handler, so removing it in the same release that adds the replacement strands anyone who has not updated. Ship both handlers, then drop the old one a release later once version adoption is high enough.

Related terms

  • Apple App Site Association (AASA)The apple-app-site-association file is a JSON document hosted at a domain's /.well-known/ path that tells iOS which app is allowed to handle which URLs on that domain.
  • assetlinks.jsonassetlinks.json is a Digital Asset Links statement file hosted at a domain's /.well-known/ path that authorises a named Android app, identified by package name and signing certificate fingerprint, to handle that domain's URLs.
  • Unattributed installsAn install is unattributed when no signal linking it to a prior ad click or link tap survived the journey through the app store, which can mean the install was organic or that the signal existed and was lost.