Skip to main content

Migrate Firebase Dynamic Links in React Native

Firebase Dynamic Links has shut down. The @ulinkly/react-native SDK bridges the native Android/iOS Ulinkly SDKs behind a single TypeScript API, so you can replace @react-native-firebase/dynamic-links while keeping your app logic in JavaScript. This guide swaps the dependency and updates your code.


1. Install the package

Expo:

npx expo install @ulinkly/react-native

Bare React Native:

npm install @ulinkly/react-native
npx install-expo-modules@latest
cd ios && pod install

Then apply native configuration (custom scheme + Associated Domains / App Links) — either via the Expo config plugin or manual native setup. This replaces the deep-link configuration you previously had for Firebase.

Not supported in Expo Go

@ulinkly/react-native is a native module — use a development build or expo prebuild, not Expo Go.


2. Configure your Ulinkly project

Follow the prerequisites from the migration overview:

  • Configuration → Android/iOS: package name, bundle ID, Team ID, URL schemes, SHA-256 fingerprints, store fallbacks.
  • Domains: verify your .shared.ly subdomain or a custom host.
  • Links: recreate Firebase short links with the right type (dynamic vs unified), or create them programmatically (step 5).

3. Initialize the SDK

Replace your Firebase initialization and dynamicLinks().onLink(...) setup with Ulinkly initialization at app startup:

import ULink from '@ulinkly/react-native';

async function initULink() {
await ULink.initialize({
apiKey: 'ULINK_API_KEY_FROM_DASHBOARD',
debug: __DEV__,
});
}

initULink().catch(console.error);

Always await initialize() before calling other methods. On Android, pre-init calls reject; on iOS they queue.


Firebase exposed dynamicLinks().getInitialLink() (cold start) and dynamicLinks().onLink() (foreground). Ulinkly unifies both into event listeners that also cover cold start automatically:

import { useEffect } from 'react';
import ULink, { ULinkResolvedData } from '@ulinkly/react-native';

export function useDeepLinks() {
useEffect(() => {
const dynSub = ULink.onDynamicLink(handleLink); // replaces onLink + getInitialLink
const uniSub = ULink.onUnifiedLink((data) => {
// platform-redirect links — open externally if appropriate
});
return () => {
dynSub.remove();
uniSub.remove();
};
}, []);
}

function handleLink(data: ULinkResolvedData) {
// Firebase: link.url + query params → Ulinkly: structured data.parameters
const screen = data.parameters?.screen as string | undefined;
// navigate based on screen / parameters
}

Mapping from Firebase concepts:

Firebase Dynamic LinksUlinkly (@ulinkly/react-native)
dynamicLinks().getInitialLink()cold-start link delivered via onDynamicLink (or ULink.getInitialDeepLink())
dynamicLinks().onLink(cb)ULink.onDynamicLink(cb) → returns a subscription; call .remove() to unsubscribe
Parsing link.url query stringstructured data.parameters (typed map)
Social meta tags on the linkdata.socialMediaTags
Manual resolution

To resolve a URL yourself (e.g. one captured by your own Linking handler), call await ULink.resolveLink(url) or await ULink.processULink(url).


Where you built links with the Firebase Builder API or the REST shortener, switch to createLink:

const response = await ULink.createLink({
domain: 'myapp.shared.ly',
type: 'dynamic',
slug: 'rn-launch',
externalId: 'rn-launch-campaign', // idempotency key — dedupes repeat calls
iosFallbackUrl: 'https://apps.apple.com/app/id123456789',
androidFallbackUrl: 'https://play.google.com/store/apps/details?id=com.example.app',
fallbackUrl: 'https://example.com/launch',
parameters: { utm_source: 'rn-app', screen: 'offer' },
});

if (response.success) {
console.log('Created link:', response.url);
}

Unified (platform-redirect) links use type: 'unified' with iosUrl / androidUrl / fallbackUrl instead of parameters. See Create Dynamic Links → React Native.


6. Validate end-to-end

  1. Trigger your new links with the adb / xcrun simctl openurl commands from Troubleshoot → Testing Deep Links.
  2. Run with debug: __DEV__ and inspect SDK logs via ULink.onLog(...) — native iOS/Android logs bubble up to JS.
  3. Watch Dashboard → Links → Analytics for clicks and per-device stats.
  4. Optionally run ulink verify -v to confirm native configuration.

Once verified, remove @react-native-firebase/dynamic-links from your package.json (and the Firebase deep-link entries from Info.plist / AndroidManifest.xml if they're no longer used). Your app is now fully backed by Ulinkly.