When migrating away from Firebase Dynamic Links, you’ll need to reimplement several backend functionalities – because of the Deprecation – that Firebase previously handled for you automatically. Here’s a detailed breakdown of what Firebase Dynamic Links provides on the backend, and what you’ll need to replace:
🔧 Firebase Dynamic Links — Backend Functionalities
- Smart Link Routing
- Detects the platform (iOS, Android, desktop) and routes the user to the appropriate destination (App Store, Play Store, website, app content).
- Handles logic like:
→ If app is installed → open app
→ If not → redirect to store/website
- Deferred Deep Linking
- Ensures that a user who installs the app after clicking a dynamic link still lands on the intended in-app content.
- Achieved by persisting the link data through install (e.g., using install referrer on Android).
- Link Data Encoding and Decoding
- Encodes in-app content info into a URL-safe format.
- Decodes it on app launch to deep link users to specific views/content.
- Analytics Tracking
- Provides click and conversion tracking per link.
- Tracks:
- Who clicked the link
- On what device
- Whether the app was installed and opened
- What channel/platform the link was clicked from
- Link Shortening and Management
- Provides short, readable URLs with analytics behind them.
- Manages the mapping from the short link to the full deep link payload.
- Custom Domain Support
- Allows using your own domain (e.g.,
app.yourdomain.com
) with HTTPS and redirection rules.
- Allows using your own domain (e.g.,
- App Store Fallbacks
- If the app is not installed, redirects to the App Store/Play Store automatically with platform-aware logic.
- App Preview Page (optional)
- Mobile web landing page that offers options like “Open app” or “Install app”, with branding.
✅ What You Need to Reimplement When Migrating
Firebase Feature | Replacement Options / Notes |
---|---|
Smart Link Routing | Build your own URL resolver backend that inspects the User-Agent or uses JS on web to detect device/platform and redirect accordingly. |
Deferred Deep Linking | Use Android Install Referrer API and iOS Universal Links + pasteboard tricks or Apple App Site Association with stored tokens. Complex but doable. |
Link Data Encoding | Encode deep link data manually (base64, query params, etc.), and parse it on app launch. |
Analytics | Use Google Analytics, Mixpanel, or self-hosted tools to track link clicks and installs. |
Link Shortening | Use services like Bitly, Rebrandly, or a custom shortener backend (e.g., YOURLS, Firebase Hosting + Cloud Functions, or Node/Go/PHP app). |
Custom Domain | Host your redirection logic on your own domain with SSL; use server-side logic (Node.js, Spring Boot, PHP, etc.). |
App Store Fallbacks | Implement fallback logic in your redirect endpoint based on device/platform. |
App Preview Page | Build a responsive mobile landing page yourself and redirect to it optionally. |
🧠 Suggested Migration Strategy
- Create your own redirect endpoint: e.g.,
/r/:code
on your backend. - Store mapping: short code → metadata (deep link URL, fallback URLs).
- Detect platform:
- Use server-side User-Agent parsing or JavaScript + mobile detection in browser.
- Redirect appropriately:
- If mobile and app installed → open app using deep link schema/intent/universal link.
- Else → fallback to app store or web.
- Track analytics:
- Log events (e.g., via webhook or analytics SDK).
- Persist data for deferred deep linking:
- Android: Use referrer ID in Play Store.
- iOS: Use a pasteboard or Apple’s
NSUserActivity
.
🛠 Tools You Might Need
- Backend Platform: Node.js, Java (Spring Boot), Go, etc.
- Database: Firebase Firestore (still usable), PostgreSQL, MongoDB.
- Link Shortener: YOURLS, Bitly, or your own logic.
- Device Detection: WURFL,
ua-parser-js
. - Analytics: Mixpanel, Google Analytics, Amplitude, Matomo.
- Install Referrer SDK: For Android (Google Play Install Referrer).
Backend (Java)
Here’s a breakdown of how to reimplement Firebase Dynamic Links backend functionalities using Java (Spring Boot). This setup gives you full control over routing, tracking, and fallback logic.
🔁 Goal
Build a Spring Boot backend that supports:
- Short links with unique codes
- Redirect logic based on platform (Android, iOS, desktop)
- Optional deferred deep linking via install referrer
- Analytics (link clicks, user agents, timestamps)
- Custom domain support (
yourdomain.com/r/abc123
)
✅ Features to Build
1. Short Link Creation
- Endpoint:
POST /links
- Request Payload:
{
"deepLink": "myapp://product/123",
"fallbackUrl": "https://yourdomain.com/product/123",
"androidPackage": "com.yourapp",
"iosAppStoreUrl": "https://apps.apple.com/app/id123456",
"webUrl": "https://yourdomain.com/product/123"
}
- Response:
{
"shortUrl": "https://yourdomain.com/r/abc123"
}
Use a unique code generator (UUID
, NanoID
, or base62) and store the mapping in a database (PostgreSQL, Mongo, etc.).
2. Link Redirect Endpoint
- Endpoint:
GET /r/{code}
Logic:
- Look up the
code
in DB - Detect device/platform:
- Use
User-Agent
or JS fallback
- Use
- Redirect:
- App installed: Redirect to custom scheme or universal link (e.g.,
myapp://product/123
) - App not installed: Redirect to fallback (App Store, Play Store, Web)
- App installed: Redirect to custom scheme or universal link (e.g.,
Sample Java Code (Spring Boot Controller):
@GetMapping("/r/{code}")
public ResponseEntity<Void> redirect(@PathVariable String code,
HttpServletRequest request) {
LinkInfo link = linkService.getByCode(code);
String userAgent = request.getHeader("User-Agent");
String redirectUrl = determineRedirectUrl(userAgent, link);
// Optionally log analytics
analyticsService.logClick(code, userAgent, request.getRemoteAddr());
return ResponseEntity.status(HttpStatus.FOUND)
.location(URI.create(redirectUrl))
.build();
}
private String determineRedirectUrl(String userAgent, LinkInfo link) {
if (userAgent.contains("Android")) {
return "intent://" + link.getDeepLink() + "#Intent;package=" + link.getAndroidPackage() + ";scheme=myapp;end";
} else if (userAgent.contains("iPhone") || userAgent.contains("iPad")) {
return link.getIosAppStoreUrl(); // or universal link if set up
} else {
return link.getWebUrl();
}
}
3. Analytics Tracking
Create a table to store:
- Timestamp
- Short code
- Device type
- User agent
- IP address
You can visualize this later via a dashboard or export to a tool like Grafana.
4. Deferred Deep Linking (Optional but Complex)
Firebase uses the Google Play Install Referrer and iOS’s Universal Link + Pasteboard tricks.
- Android:
- Use
com.android.installreferrer
library - Pass the code (
abc123
) to the Play Store referrer - Your app reads it on install and requests the real deep link
- Use
- Backend stores the mapping between referrer ID and deep link so the app can resolve it post-install.
5. Optional Preview Page
If you’d like to offer an app preview with “Install” or “Open” options, create an HTML view at /r/{code}
(instead of direct redirect) with:
- JS to auto-open app or fallback to install
- Branding, install button, instructions
🧰 Tech Stack Summary
Component | Tech Stack |
---|---|
Backend | Java, Spring Boot |
Database (DB) | PostgreSQL or MongoDB |
Analytics | Simple DB logging + optional dashboard |
Link Shortener | Base62 generator, UUID, or NanoID |
Deferred Linking | Google Install Referrer + app coordination |
Hosting | Any Java-supporting cloud (Heroku, AWS, etc.) |
How the redirect endpoint could know if the app is installed
Can a backend know if the app is installed?
➡️ No, not directly.
The backend cannot reliably detect if the app is installed on a user’s device just from an HTTP request (e.g. the User-Agent
). That information isn’t sent over the network.
Instead, app installation detection is handled on the client side, typically via JavaScript or native mobile behavior — not the backend.
✅ Practical Approaches (How It’s Usually Done)Here are the main strategies developers use to simulate or infer installation status:
✅ 1. Redirect to a Custom URI Scheme / Universal Link
- If the app is installed, the OS will try to open the app.
- If it’s not installed:
- Android: You can fall back using
intent://...
URLs. - iOS: You can’t detect failure; user just stays on Safari unless you use a preview page.
- Android: You can fall back using
On Android
intent://product/123#Intent;scheme=myapp;package=com.yourapp;end
- Works if the app is installed
- Otherwise, it opens the Play Store or fails silently (depending on browser/OS version)
On iOS
- Use a Universal Link like
https://yourdomain.com/product/123
- If the app is installed → opens the app
- If not → opens the web URL (or App Store fallback)
iOS only supports universal links — not custom schemes — in Safari. Other browsers behave inconsistently.
✅ 2. Use a JavaScript “App Detection” Trick on the Preview Page
Redirect users to a landing/preview page that:
- Tries to open the app
- Waits a short time
- Redirects to the App Store if the app did not open
Sample JS (simplified):
<script>
const now = Date.now();
const appUrl = 'myapp://product/123';
const fallbackUrl = 'https://apps.apple.com/app/id123456';
// Try to open app
window.location = appUrl;
setTimeout(() => {
// If app wasn't opened, redirect to store
if (Date.now() - now < 1500) {
window.location = fallbackUrl;
}
}, 1200);
</script>
⚠️ This is not reliable on all browsers and OS versions, but is a widely used workaround.
✅ 3. Use Firebase or Branch.io SDK (on Client Side)
If you really need to know if the app is installed, you’d need:
- A custom SDK in your app that reports back to your backend
- Or you use 3rd-party services like:
- Branch.io
- Appsflyer
- Firebase Dynamic Links (which you’re leaving)
But you still won’t get this from the backend alone.
🔁 Backend Role in All This
Your backend can:
Task | Description |
---|---|
Generate links | Store metadata for redirection |
Detect platform | Use User-Agent headers |
Redirect | Send users to app link (intent, universal) or fallback |
Serve preview page | A page that attempts to open the app via JS |
Track analytics | Log redirects, user-agents, click timestamps |
But it cannot detect installation status.