π₯ Migrate from Firebase Dynamic Links
Google deprecated Firebase Dynamic Links and the service has been shut down. ChottuLink is a drop-in replacement that supports the same core capabilities β short links, deferred deep linking, platform-aware routing, and analytics β across more platforms.
ChottuLink auto-generates and hosts your apple-app-site-association (iOS) and assetlinks.json (Android) files, manages HTTPS certificates, and handles domain verification β no manual server setup required.
π Prerequisitesβ
Before you begin migrating, make sure you have the following ready:
- A ChottuLink account β Sign up for free if you haven't already
- Your Firebase Dynamic Links configuration β Note down your:
- Firebase
*.page.linkdomain (or custom domain) - iOS settings: Bundle ID, Team ID, App Store ID
- Android settings: Package Name, SHA-256 fingerprints
- Any existing short links you need to recreate
- Firebase
- Access to your app's codebase β You'll need to update SDK dependencies, configuration files, and code on all platforms
- A list of active Firebase links β Export destination URLs for any links you need to migrate (Firebase links stop working after the shutdown)
Firebase Dynamic Links have been shut down. Existing *.page.link URLs no longer redirect. Start your migration as soon as possible to minimize user impact.
Migration Overviewβ
Once you have the above ready, follow these steps to complete the migration:
- Set up the ChottuLink Dashboard β Configure your project, choose your subdomain, and set up iOS/Android redirects (replaces Firebase Console setup)
- Migrate the SDK β Remove Firebase Dynamic Links SDK, install ChottuLink SDK, and update your app code
- Create your dynamic links on ChottuLink β Re-create your links using the Dashboard or REST API
- Handle deep link redirects inside your app β Update link receiving and handling code to use the ChottuLink SDK (covered in Step 2)
- Re-create your existing links β Bulk-migrate active Firebase links using the REST API or Dashboard
πΊοΈ Concept Mappingβ
Use this table as a quick reference when migrating your codebase.
Terminology
| Firebase Dynamic Links | ChottuLink | Notes |
|---|---|---|
| Firebase project | ChottuLink project / organization | Created at app.chottulink.com |
*.page.link domain | *.chottu.link subdomain | Chosen during onboarding |
| Firebase Console | ChottuLink Dashboard | app.chottulink.com |
google-services.json / GoogleService-Info.plist | Mobile SDK API key (chottulink_xxx) | Found under Dashboard > Keys |
| Firebase Web API Key | REST API key (c_api_xxx) | Found under Dashboard > Keys |
DynamicLinkParameters / DynamicLinkComponents | CLDynamicLinkBuilder (iOS) / ChottuLink.createDynamicLink() (Android) | Builder pattern on both platforms |
FirebaseDynamicLinks.getInstance().getDynamicLink() | ChottuLink.getAppLinkData() (Android) / ChottuLinkDelegate (iOS) | Receive & resolve links |
socialMetaTagParameters | .setSocialParameters(title:description:imageUrl:) | First-class API on all platforms |
| Manual UTM in URL | .setUTMParameters(source:medium:campaign:) | Built-in SDK support |
π§ Step 1 β Set Up ChottuLink Dashboardβ
Before changing any code, configure your project on the ChottuLink Dashboard. This replaces the Firebase Console configuration.
- Create an account at app.chottulink.com/register
- Choose a subdomain (e.g.
yourapp.chottu.link) β this replaces your*.page.linkdomain - Set a fallback URL β the default redirect when the app is not installed
- Configure iOS β Apple Team ID, Bundle Identifier, App Store ID, enable Universal Links β Full details: iOS Integration
- Configure Android β Package Name, SHA-256 fingerprints, enable App Links β Full details: Android Integration
- Copy your API keys from Dashboard > Keys
ChottuLink uses two key types: a Mobile SDK key (chottulink_xxx) for client SDKs and a REST API key (c_api_xxx) for server-side calls. Firebase used a single API key for both β make sure you use the correct one.
For the full onboarding walkthrough, see the Getting Started guide.
π¦ Step 2 β Migrate the SDKβ
- iOS
- Android
- Flutter
- React Native
- Capacitor / Ionic
- Unity
Remove Firebase Dynamic Linksβ
# If using CocoaPods, remove from Podfile:
# pod 'Firebase/DynamicLinks'
# Then run: pod install
# If using SPM, remove FirebaseDynamicLinks package from Xcode
- Remove
GoogleService-Info.plistif it was only used for Dynamic Links - Remove the old Associated Domain:
applinks:yourapp.page.link
Install ChottuLinkβ
Add the SDK via Swift Package Manager:
https://github.com/ConnectingDotsInfotech/chottulink-ios-sdk.git
Or see iOS Installation for manual XCFramework setup.
Update Configurationβ
In Xcode β Signing & Capabilities β Associated Domains, replace:
- applinks:yourapp.page.link
+ applinks:yourapp.chottu.link
Update Initializationβ
// BEFORE (Firebase)
import Firebase
FirebaseApp.configure()
// AFTER (ChottuLink)
import ChottuLinkSDK
let config = CLConfiguration(apiKey: "your-mobile-sdk-key", delegate: self)
ChottuLink.initialize(config: config)
Update Link Creationβ
// BEFORE (Firebase)
guard let link = URL(string: "https://yourapp.com/content") else { return }
let components = DynamicLinkComponents(link: link, domainURIPrefix: "https://yourapp.page.link")
components?.iOSParameters = DynamicLinkIOSParameters(bundleID: "com.yourapp.ios")
components?.shorten { url, warnings, error in
guard let shortURL = url else { return }
// use shortURL
}
// AFTER (ChottuLink)
let builder = CLDynamicLinkBuilder(
destinationURL: "https://yourapp.com/content",
domain: "yourapp.chottu.link"
)
.setIOSBehaviour(.app)
.setAndroidBehaviour(.app)
.setLinkName("my-link")
.build()
Task {
do {
let shortURL = try await ChottuLink.createDynamicLink(for: builder)
// use shortURL
} catch {
print("Error: \(error)")
}
}
Update Link Receivingβ
// BEFORE (Firebase)
func application(_ application: UIApplication, continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
let handled = DynamicLinks.dynamicLinks().handleUniversalLink(userActivity.webpageURL!) { link, error in
guard let deepLink = link?.url else { return }
// handle deepLink
}
return handled
}
// AFTER (ChottuLink) β Implement ChottuLinkDelegate
func chottuLink(didResolveDeepLink link: URL, metadata: [String : Any]?) {
print("Link received: \(link.absoluteString)")
// Navigate based on link
}
func chottuLink(didFailToResolveDeepLink originalURL: URL?, error: any Error) {
print("Error: \(error.localizedDescription)")
}
And in your SwiftUI view or SceneDelegate, forward links to the SDK:
.onOpenURL { url in
ChottuLink.handleLink(url)
}
β Full details: iOS Setup Β· Create Links Β· Receive Links
Remove Firebaseβ
// Remove from app/build.gradle:
// implementation 'com.google.firebase:firebase-dynamic-links'
// implementation 'com.google.firebase:firebase-dynamic-links-ktx'
- Remove
google-services.jsonif it was only used for Dynamic Links - Remove the
com.google.gms.google-servicesplugin if no longer needed - Remove old intent-filter entries pointing to
yourapp.page.link
Install ChottuLinkβ
Add to your app/build.gradle:
dependencies {
implementation 'com.chottulink:android-sdk:1.1.2'
}
Update Configurationβ
In AndroidManifest.xml, replace the host in your intent-filter:
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https"
- android:host="yourapp.page.link"/>
+ android:host="yourapp.chottu.link"/>
</intent-filter>
Update Initializationβ
// BEFORE (Firebase)
// Firebase initializes automatically via google-services.json
// AFTER (ChottuLink) β in your Application class:
import com.chottulink.lib.ChottuLink;
public class YourApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
ChottuLink.init(this, "YOUR_MOBILE_SDK_KEY");
}
}
Register the Application class in your manifest:
<application android:name=".YourApplication" ... >
Update Link Creationβ
// BEFORE (Firebase)
DynamicLink dynamicLink = FirebaseDynamicLinks.getInstance().createDynamicLink()
.setLink(Uri.parse("https://yourapp.com/content"))
.setDomainUriPrefix("https://yourapp.page.link")
.buildDynamicLink();
// AFTER (ChottuLink)
ChottuLink.createDynamicLink()
.setLink(Uri.parse("https://yourapp.com/content"))
.setDomain("yourapp.chottu.link")
.androidBehavior(DynamicLink.BEHAVIOR_APP)
.iosBehavior(DynamicLink.BEHAVIOR_APP)
.setLinkName("my-link")
.build()
.addOnSuccessListener(dynamicLink -> {
String shortUrl = dynamicLink.getUri().toString();
})
.addOnFailureListener(e -> {
Log.e("ChottuLink", "Error", e);
});
Update Link Receivingβ
// BEFORE (Firebase)
FirebaseDynamicLinks.getInstance()
.getDynamicLink(getIntent())
.addOnSuccessListener(pendingDynamicLinkData -> {
Uri deepLink = pendingDynamicLinkData.getLink();
});
// AFTER (ChottuLink)
ChottuLink.getAppLinkData(getIntent())
.addOnSuccessListener(result -> {
if (result != null && result.getLink() != null) {
String link = result.getLink().toString();
// Navigate based on link
}
});
β Full details: Android Setup Β· Create Links Β· Receive Links
Remove Firebase Dynamic Linksβ
# Remove from pubspec.yaml:
# firebase_dynamic_links: ^x.x.x
# firebase_core: ^x.x.x (if only used for DL)
Then run flutter pub get.
Install ChottuLinkβ
dependencies:
chottu_link: ^1.0.19
flutter pub get
Update Platform Configurationβ
iOS β Update Associated Domains in Xcode:
- applinks:yourapp.page.link
+ applinks:yourapp.chottu.link
Android β Update AndroidManifest.xml host:
- <data android:host="yourapp.page.link" android:scheme="https"/>
+ <data android:host="yourapp.chottu.link" android:scheme="https"/>
Also add in your manifest activity:
<meta-data android:name="flutter_deeplinking_enabled" android:value="false"/>
Update Initializationβ
// BEFORE (Firebase)
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_dynamic_links/firebase_dynamic_links.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
// AFTER (ChottuLink)
import 'package:chottu_link/chottu_link.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await ChottuLink.init(apiKey: "your_api_key_here");
runApp(MyApp());
}
β Full details: Flutter Setup Β· Create Links Β· Receive Links
Remove Firebase Dynamic Linksβ
npm uninstall @react-native-firebase/dynamic-links
# Also remove @react-native-firebase/app if only used for DL
For iOS, run cd ios && pod install && cd .. after uninstalling.
Install ChottuLinkβ
# Recommended (bridge-based)
npm install react-native-chottulink-sdk --save
# OR Nitro variant (RN 0.76.9+, bare RN only)
npm install chottulink-rn-sdk react-native-nitro-modules
For iOS: cd ios && pod install && cd ..
Update Platform Configurationβ
iOS β Update Associated Domains in Xcode:
- applinks:yourapp.page.link
+ applinks:yourapp.chottu.link
Android β Update android/app/src/main/AndroidManifest.xml host:
- <data android:scheme="https" android:host="yourapp.page.link"/>
+ <data android:scheme="https" android:host="yourapp.chottu.link"/>
Update Initializationβ
// BEFORE (Firebase)
import dynamicLinks from '@react-native-firebase/dynamic-links';
const link = await dynamicLinks().getInitialLink();
// AFTER (ChottuLink)
import { initializeChottuLink } from 'react-native-chottulink-sdk';
initializeChottuLink('your-api-key-here');
Update Link Receivingβ
// BEFORE (Firebase)
const unsubscribe = dynamicLinks().onLink(({ url }) => {
handleDeepLink(url);
});
// AFTER (ChottuLink)
import { NativeEventEmitter, NativeModules } from 'react-native';
const { ChottuLinkEventEmitter } = NativeModules;
const eventEmitter = new NativeEventEmitter(ChottuLinkEventEmitter);
const subscription = eventEmitter.addListener('ChottuLinkDeepLinkResolved', data => {
console.log('URL:', data.url);
console.log('Metadata:', data.metadata);
});
Firebase Dynamic Links never officially supported Expo. ChottuLink offers first-class Expo support via expo-dev-client. See the Expo Integration guide.
β Full details: React Native Setup Β· Expo Setup
Remove Firebase Dynamic Linksβ
Remove any Firebase Dynamic Links plugin you were using.
Install ChottuLinkβ
npm install capacitor-chottulink-sdk
npx cap sync
Update Platform Configurationβ
iOS β Update Associated Domains in Xcode (npx cap open ios):
- applinks:yourapp.page.link
+ applinks:yourapp.chottu.link
Android β Update android/app/src/main/AndroidManifest.xml host:
- <data android:host="yourapp.page.link"/>
+ <data android:host="yourapp.chottu.link"/>
Update Initializationβ
import { ChottuLinkIonicSDK } from 'capacitor-chottulink-sdk';
ChottuLinkIonicSDK.initialize({ apiKey: 'YOUR_API_KEY' })
.then(() => console.log('ChottuLink initialized'))
.catch((error) => console.error('Error:', error));
β Full details: Capacitor Setup Β· Create Links Β· Receive Links
Remove Firebase Dynamic Linksβ
Remove the Firebase Dynamic Links module from your Unity project (delete the Firebase DL .unitypackage assets).
Install ChottuLinkβ
- Download the ChottuLink Unity SDK
- Import via Assets β Import Package β Custom Package
Update Platform Configurationβ
Same iOS Associated Domains and Android manifest changes as above.
Update Initializationβ
// BEFORE (Firebase)
FirebaseDynamicLinks.DynamicLinkReceived += OnDynamicLink;
// AFTER (ChottuLink)
void Start() {
ChottuLink.Init("your_api_key");
}
β Full details: Unity Setup Β· Create Links Β· Receive Links
π Step 3 β Migrate REST API Callsβ
If you create or manage links from your backend, update your server-side integration.
Endpoint Mappingβ
| Operation | Firebase Dynamic Links | ChottuLink |
|---|---|---|
| Create short link | POST firebasedynamiclinks.googleapis.com/v1/shortLinks?key={KEY} | POST api2.chottulink.com/chotuCore/pa/v1/create-link |
| Get link analytics | GET firebasedynamiclinks.googleapis.com/v1/{shortLink}/linkStats?key={KEY} | POST api2.chottulink.com/chotuCore/pa/v1/analytics |
Authentication Changeβ
- # Firebase: API key as query parameter
- POST https://firebasedynamiclinks.googleapis.com/v1/shortLinks?key=YOUR_FIREBASE_KEY
+ # ChottuLink: API key as request header
+ POST https://api2.chottulink.com/chotuCore/pa/v1/create-link
+ API-KEY: c_api_xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Example: Create a Linkβ
curl --location 'https://api2.chottulink.com/chotuCore/pa/v1/create-link' \
--header 'API-KEY: c_api_xxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data '{
"domain": "yourapp.chottu.link",
"destination_url": "https://yourapp.com/content",
"link_name": "Summer Sale",
"ios_behavior": 2,
"android_behavior": 2,
"utm_source": "email",
"utm_medium": "newsletter",
"utm_campaign": "summer2025"
}'
ChottuLink-Exclusive Capabilitiesβ
These REST API features were not available in Firebase Dynamic Links:
| Capability | Endpoint | Docs |
|---|---|---|
| List all links (paginated) | GET .../pa/v1/links/page | List Links |
| Update link properties | PATCH .../pa/v1/update-link/{linkId} | Update Link |
| Enable / disable a link | PATCH .../pa/v1/links/change-status/{linkId} | Enable/Disable |
| Get link info by short URL | POST .../pa/v1/links/info | Get Link Info |
| Install analytics (paid) | POST .../pa/v1/install-analytics | Install Analytics |
For a ready-to-use API testing setup, import the ChottuLink Postman Collection.
π Step 4 β Migrate Existing Linksβ
URLs on *.page.link domains are no longer functional after the Firebase Dynamic Links shutdown. You must re-create critical links on ChottuLink and update all references (marketing emails, QR codes, social media posts, printed materials, etc.).
Strategyβ
- Export your existing Firebase links and their destination URLs
- Bulk-create equivalent ChottuLink links using the REST API
- Update all references in your marketing materials, apps, and websites
Single Link (curl)β
curl --location 'https://api2.chottulink.com/chotuCore/pa/v1/create-link' \
--header 'API-KEY: c_api_xxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data '{
"domain": "yourapp.chottu.link",
"destination_url": "https://yourapp.com/promo",
"link_name": "Summer Promo",
"selected_path": "summer-promo",
"ios_behavior": 2,
"android_behavior": 2
}'
Bulk Migration Script (Python)β
Expand to see the migration script
Prepare a CSV file (links.csv) with your Firebase links:
firebase_link,destination_url,link_name,path
https://yourapp.page.link/abc,https://yourapp.com/promo,Summer Promo,summer-promo
https://yourapp.page.link/xyz,https://yourapp.com/refer,Referral,refer-friend
Then run this script:
import csv
import requests
import time
API_KEY = "c_api_xxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
DOMAIN = "yourapp.chottu.link"
BASE_URL = "https://api2.chottulink.com/chotuCore/pa/v1/create-link"
headers = {
"API-KEY": API_KEY,
"Content-Type": "application/json"
}
with open("links.csv", newline="") as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
payload = {
"domain": DOMAIN,
"destination_url": row["destination_url"],
"link_name": row["link_name"],
"selected_path": row["path"],
"ios_behavior": 2,
"android_behavior": 2,
}
response = requests.post(BASE_URL, json=payload, headers=headers)
if response.status_code == 201:
data = response.json()
print(f"Created: {data['short_url']} (was: {row['firebase_link']})")
else:
print(f"FAILED: {row['firebase_link']} -> {response.status_code} {response.text}")
time.sleep(0.5)
β¨ What's Better in ChottuLinkβ
ChottuLink is not just a Firebase replacement β it improves on several areas:
| Capability | Firebase Dynamic Links | ChottuLink |
|---|---|---|
| Update links after creation | Not supported (immutable) | Supported via PATCH API |
| Enable / disable links | Not supported | Supported β pause campaigns without deleting |
| UTM parameters | Manual URL construction | First-class SDK and API support |
| Social previews | Separate socialMetaTagParameters object | Built-in setSocialParameters() on all platforms |
| Install analytics | Not available | Available via API (paid plan) |
| Platform support | iOS, Android, Flutter, Unity | iOS, Android, Flutter, React Native, Expo, Capacitor/Ionic, Unity |
| Custom link paths | Limited | Full control with selected_path |
β Migration Checklistβ
Use this checklist to track your migration progress:
- Created ChottuLink account and configured project
- Chose subdomain and set fallback URL
- Configured iOS settings (Team ID, Bundle ID, Universal Links)
- Configured Android settings (Package Name, SHA-256 fingerprints, App Links)
- Removed Firebase Dynamic Links SDK from all platforms
- Installed ChottuLink SDK on all platforms
- Updated Associated Domains (iOS) and intent-filters (Android)
- Updated SDK initialization code
- Updated link creation code
- Updated link receiving / handling code
- Migrated server-side REST API calls
- Re-created critical existing links via REST API
- Tested deep links on both iOS and Android
- Tested deferred deep links on both iOS and Android
- Updated marketing materials, emails, and QR codes with new URLs
π§© Troubleshootingβ
For general deep linking issues, see the full Troubleshooting guide. Below are migration-specific tips.
Domain verification takes time
After switching from *.page.link to *.chottu.link, both Apple and Google need time (minutes to hours) to verify the new domain. Be patient and test from a messaging app (WhatsApp, Telegram) rather than the browser URL bar.
Remove old Associated Domains
If you leave applinks:yourapp.page.link in your iOS entitlements alongside the new ChottuLink domain, it can cause conflicts. Remove the old entry.
SHA-256 fingerprints must be complete Add all SHA-256 fingerprints (debug keystore, release keystore, and every developer's debug keystore) in the ChottuLink Dashboard. Missing fingerprints are the most common cause of Android App Links failing.
Deferred deep links not working
Ensure the ChottuLink SDK is initialized before the first activity/screen loads. For Android, use ChottuLink.getAppLinkData(getIntent()) in the activity that launches right after the splash screen.
Play Store / App Store opens instead of the app
This is expected for the first few hours after setup while domain verification completes. Use adb shell pm get-app-links <packageName> to check Android verification status. See the Troubleshooting guide for step-by-step verification instructions.
π¬ Need Help?β
If you run into issues during migration:
- Chat with us on the ChottuLink Dashboard
- Email support at help@chottulink.com