

Implement Deep linking in react native with Firebase dynamic links, One of the popular features of mobile apps is sharing content with others, such as products, articles, or videos. In this scenario, we will discuss how to implement Firebase Dynamic Links in a React Native app to enable sharing of products with deep linking to the product page.
You can use Firebase Dynamic Links to share deep links to your app. You can use these deep links to redirect users to specific content within your app.
Table of Contents
To implement Firebase Dynamic Links in a React Native app, you need to follow a few steps.
Step 1: Firebase Setup (if you already did it you can skip it)
Setup Firebase in React Native. The @react-native-firebase/app module must be installed before using any other Firebase service. if you have already setup then Skip this First Step.
I’m assuming that you followed the first step or that you have already installed the Firebase base module and created a React Native project on Firebase. Now we can proceed with Firebase Dynamic Links.
Prerequisite for iOS
Before setting up Dynamic Links on iOS, it is necessary to have an Apple developer account set up.
To find your Team ID on Apple Developer Account, navigate to the Account tab. Your Team ID will be displayed in the top right corner of the page, beside your name.

In your Firebase console, add an App Store ID and Team ID to your app. In case you do not have an App Store ID yet, you can temporarily use any number. Your Team ID can be found in your Apple developer console.


Installation:
npm install @react-native-firebase/dynamic-links
# If you're developing your app using iOS, run this command
cd ios/ && pod install
Step 2: Firebase Dynamic Links Setup on firebase
Go to: https://console.firebase.google.com/
To use this service, you’ll need to log in to your Firebase console, select your project, select Engage tab from the sidebar, click on the dynamic links, and select Get Started.

Now you get the Modal where you must enter your domain name. If you don’t have a domain name, don’t worry, just type any name and in the future, you can change it.
In this test example, we’ve created one for https://mrdevgeekdeeplink.page.link. After adding just click on continue and finally finish it

Now your Link is created:


After that just click on the New Dynamic Link. You’ll see the Further steps.

you can change the text after / but I’m continuing with this dummy text.

If you don’t have your own domain, just add my domain. When you open this link in a browser, it redirects you to your website or a placeholder website like mine or Google.com.

if you are configuring only for the Android app. Step three select the first one Open the deep link URL in a browser. Otherwise Choose Open the deep link URL in your Apple app and select your app, like mine is com.deeplinkpractice

if you are configuring only for the iOS app. Step three select the first one Open the deep link URL in a browser. otherwise Choose Open the deep link URL in your Android app and select your app, like mine is DeepLinking

It is an optional step, but it is a great way to promote your product on social media. After adding this, your product will look like this on social media. otherwise just shows the Link URL without any Image preview

Android Setup:
Follow these instructions to create an SHA-256 fingerprint for your app, and add it to your Firebase account. if you already added it to your firebase console you can skip this step. This step is necessary

Test Your Link is Working or Not:
- Test the domain you created in your Firebase console (the first step in Firebase Setup). Go to [your-domain]/.well-known/assetlinks.json in your browser. The response will have a target object containing a package name. Your app’s package name should be displayed here. Do not proceed until you see this. Registration may take a while
- Add your domains to the android/app/src/main/AndroidManifest.xml so that your app knows what links to open in the app. Refer to the official docs for example code.

Simulate a user opening the link by pasting it into a text message, notepad, or email, and pressing it. test your dynamic link which you created earlier like mine: https://mrdeeplinkingpractice.page.link/Zi7X.
iOS Setup:
At the moment, a workaround is necessary for iOS to enable method swizzling. The workaround has been explained in detail in a this comment on Github. Without it, there is a possibility of inconsistent dynamic link matching behavior. If you are using Expo Managed Workflow, make sure to install the @react-native-firebase/dynamic-links config plugin, which will apply the workaround automatically.
the code from this Github Comment you can check for details: Github Comment.
developer mentioned:
I had a on iOS.
(although to be precise, it was getInitialLink() always returning null).
locate the /ios/{projectName}/AppDelegate.mm file (or AppDelegate.m for older react-native versions) and follow these steps:
#import <RNFBDynamicLinksAppDelegateInterceptor.h> // add this line
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[RNFBDynamicLinksAppDelegateInterceptor sharedInstance]; // add this line
//-------
// other code
//-------
}
To verify the domain you created in your Firebase console during the first step of the Firebase setup, open your browser and navigate to “[your domain]/apple-app-site-association”. The response will include a details array property containing an object with the appID property. This app ID will correspond to your app’s app ID. Please note that it may take some time for your domain to register, so make sure it is registered before proceeding.

After confirming that your domain is registered, proceed to your Apple developer console to create a provisioning profile for your app. Before proceeding, make sure that you have enabled the Associated Domain capability.
There are two options for creating the provisioning profile. One is to create it manually, and the other is to select Automatic manage signing. If you choose Automatic manage signing option will automatically handle the provisioning profile when you make changes or add something in Xcode.
In Xcode, open your project and navigate to your app under the TARGETS header. Click on the Signing & Capabilities tab. Ensure that your Team is registered and that the Provisioning Profile field is completed. To associate your domain with your app, add the domain you created in your Firebase console to the Associated Domains and prefix it with “applinks:”.


Navigate to the Info tab in Xcode and add a URL Type to your project. You can name the Identifier as Bundle Id or anything else you prefer. Add your bundle identifier to the URL Schemes property.

Usage:
In our scenario, we want users to be able to share products with others. We use Firebase Dynamic Links to generate a unique link for each product. This link can be shared via messaging apps, email, or social media. When another user clicks on the link, they will be redirected to the product page within the app.
Implementing Firebase Dynamic Links in a React Native app is a great way to enable deep linking and enhance the user experience of your app.
The basic implementation of this project includes stack navigation from React Navigation and Axios for fetching dummy data. already implemented
import {
FlatList,
Image,
Pressable,
SafeAreaView,
StyleSheet,
Text,
View,
} from 'react-native';
import React, {useEffect, useState } from 'react';
import { useNavigation } from '@react-navigation/native';
const Home = () => {
const [data, setData] = useState([]);
const navigation = useNavigation()
const getApiData = () => {
fetch(`https://dummyjson.com/products?skip=0&limit=12`)
.then(res => res.json())
.then(json => {
setData([...data, ...json.products]);
})
.catch(error => {
console.log('Error:', error);
});
};
console.log('data from state:', data);
useEffect(() => {
getApiData();
}, []);
const keyExtractor = key => `${key.id}`;
const renderItem = ({ item, index }) => {
return (
<Pressable onPress={() => navigation.navigate('ProductDetail', { productId: item.id })} style={styles.flatStyle}>
<Image style={styles.imgStyle} source={{ uri: item.thumbnail }} />
<View style={styles.footerStyle}>
<Text style={styles.textStyle}>{item.brand}</Text>
<Text style={styles.textStyle}>{item.price}$</Text>
</View>
<Text>{item.description}</Text>
</Pressable>
);
};
const itemSeparatorComponent = () => {
return <View style={{ height: 20 }} />;
};
return (
<SafeAreaView style={styles.container}>
<FlatList
data={data}
renderItem={renderItem}
keyExtractor={keyExtractor}
ItemSeparatorComponent={itemSeparatorComponent}
/>
</SafeAreaView>
);
};
export default Home;
const styles = StyleSheet.create({
container: {
flex: 1,
paddingHorizontal: 16,
},
flatStyle: {
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 1,
},
shadowOpacity: 0.22,
shadowRadius: 2.22,
elevation: 2,
backgroundColor: 'white',
margin: 2,
borderRadius: 8,
padding: 8,
},
imgStyle: {
width: '100%',
height: 200,
borderRadius: 10,
},
footerStyle: {
flexDirection: 'row',
justifyContent: 'space-between',
marginVertical: 10,
},
textStyle: {
fontSize: 16,
fontWeight: '600',
},
});
This is a React Native code snippet that fetches data from an API and displays it in a FlatList on the Home screen. The component imports several React Native modules, such as FlatList, Image, Pressable, SafeAreaView, StyleSheet, and Text, as well as the useNavigation hook from @react-navigation/native.
The Home component initializes the state with an empty array of data and then calls the getApiData function using the useEffect hook to fetch the API data and update the state accordingly. A unique key is set for each item in the list using the keyExtractor function.
The renderItem function renders each item in the FlatList, returning a Pressable component displaying the product image, brand, price, and description. When a user clicks on a product, the navigation.navigate function navigates to the ProductDetail screen with the productId parameter.
The itemSeparatorComponent function is used to add a space between each item in the list.
Lastly, the Home component returns a SafeAreaView component that contains a FlatList component that accepts data, renderItem, keyExtractor, and itemSeparatorComponent props. The various components are styled using StyleSheet.
import { ActivityIndicator, Image, Pressable, Share, StyleSheet, Text, View } from 'react-native';
import React, { useEffect, useState } from 'react';
import axios from 'axios';
import dynamicLinks from '@react-native-firebase/dynamic-links';
const ProductDetail = ({ route }) => {
const { productId } = route.params;
const [productData, setProductData] = useState({});
const [loading, setLoading] = useState(true)
const getSingleProduct = async () => {
try {
const result = await axios
.get(`https://dummyjson.com/products/${productId}`)
const data = result.data
setProductData(data);
setLoading(false)
} catch (error) {
console.log('Error:', error);
}
};
console.log('data from state:', productData);
useEffect(() => {
getSingleProduct();
}, []);
const generateLink = async () => {
try {
const link = await dynamicLinks().buildShortLink({
link: `https://mrdeeplinkingpractice.page.link/Zi7X?productId=${productId}`,
domainUriPrefix: 'https://mrdeeplinkingpractice.page.link',
android: {
packageName: 'com.deeplinkpractice',
},
ios: {
appStoreId: '123456789',
bundleId: 'com.deepLinkingProjectBundleId',
},
}, dynamicLinks.ShortLinkType.DEFAULT)
console.log('link:', link)
return link
} catch (error) {
console.log('Generating Link Error:', error)
}
}
const shareProduct = async () => {
const getLink = await generateLink()
try {
Share.share({
message: getLink,
});
} catch (error) {
console.log('Sharing Error:', error)
}
}
return (
<>
{
loading ? <ActivityIndicator /> : <View style={styles.container}>
<View style={styles.flatStyle}>
<Image style={styles.imgStyle} source={{ uri: productData?.thumbnail }} />
<View style={styles.bodyStyle}>
<View style={styles.innerBox}>
<Text style={styles.textTitle}>{productData?.brand}</Text>
<Text style={styles.textStyle}>{productData?.price}$</Text>
</View>
<Text>{productData?.description}</Text>
</View>
<View style={styles.footer}>
<Pressable onPress={shareProduct} style={styles.btn}>
<Text style={styles.btnTitle}>
Share Product
</Text>
</Pressable>
</View>
</View>
</View>
}
</>
);
};
export default ProductDetail;
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white'
},
imgStyle: {
width: '100%',
height: 250,
resizeMode: 'cover'
},
bodyStyle: {
justifyContent: 'space-between',
marginVertical: 10,
marginHorizontal: 20
},
innerBox: {
flexDirection: 'row',
justifyContent: 'space-between'
},
textTitle: {
fontSize: 20,
fontWeight: '600',
},
textStyle: {
fontSize: 16,
fontWeight: '600',
},
footer: {
marginVertical: 20,
marginHorizontal: 20
},
btn: {
backgroundColor: '#797ee630',
padding: 20,
borderRadius: 10
},
btnTitle: {
color: '#797ee6',
fontSize: 20,
textAlign: 'center'
}
});
The “ProductDetail” component displays the details of a single product.
This component imports necessary components from React Native as well as some external libraries such as “Axios” for making HTTP requests and “@react-native-firebase/dynamic-links” for generating dynamic links.
It receives the “productId” as a parameter from the “route” object, which is used to make an HTTP request to retrieve the product details from the “dummyjson” API.
In this component, the loading status and the state of the product data are managed using React’s “useState” hook. Once the product data has been fetched successfully, the loading status is changed to false.
The “generateLink” function generates a short dynamic link using the “dynamicLinks()” function from the “@react-native-firebase/dynamic-links” library. The generated link includes the “productId” as a query parameter.
The “shareProduct” function uses the “generateLink” function to get the dynamic link and uses the “Share” component from React Native to share the link.
Lastly, the component renders the product details, including the product image, title, price, and description. It also includes a “Share Product” button, which calls the “shareProduct” function to share the product link. If the product data is not yet loaded, the component displays an activity indicator (Loader).
import React, { useEffect } from 'react'
import dynamicLinks from '@react-native-firebase/dynamic-links';
import { NavigationContainer, useNavigation } from '@react-navigation/native';
import Navigation from './src/Navigaiton/Navigation';
const App = () => {
const HandleDeepLinking = () => {
const {navigate} = useNavigation()
const handleDynamicLinks = async (link) => {
console.log('Foreground link handling:', link)
let productId = link.url.split('=').pop()
console.log('productId:', productId,)
navigate('ProductDetail', { productId: productId })
}
useEffect(() => {
const unsubscribe = dynamicLinks().onLink(handleDynamicLinks)
return () => unsubscribe()
}, [])
return null
}
return (
<NavigationContainer>
<HandleDeepLinking />
<Navigation />
</NavigationContainer>
)
}
export default App
This is a React Native app component that handles dynamic links using the @react-native-firebase/dynamic-links library.
It starts by importing necessary dependencies such as React, useEffect, and useNavigation from @react-navigation/native and the dynamicLinks from @react-native-firebase/dynamic-links.
The component App defines another component called HandleDeepLinking which is responsible for handling the dynamic links. It uses useNavigation hook to navigate to the appropriate screen when a dynamic link is clicked.
The handleDynamicLinks function is called when a dynamic link is clicked and this function takes the link as its parameter. then extracts the productId from the URL of the link using the split method and navigates to the ProductDetail screen with the productId as a parameter.
The useEffect hook is used to listen to the dynamic links when the component is mounted, and a function is returned to unsubscribe from listening to dynamic links when the component is unmounted.
Lastly, the NavigationContainer wraps HandleDeepLinking and Navigation components to use the navigations in the application.
FAQ
What are Dynamic Links in React Native Firebase?
Dynamic Links are deep links that allow users to directly access specific content or features within a mobile app. They are cross-platform and can be used to redirect users to the app store, specific content within an app, or even external websites.
How do I implement Dynamic Links in my React Native Firebase app?
You can implement Dynamic Links by using the @react-native-firebase/dynamic-links package, which provides a set of APIs for creating, handling, and retrieving Dynamic Links.
Can I customize the appearance of Dynamic Links?
Yes, you can customize the appearance of Dynamic Links by using Firebase Dynamic Links parameters, such as setting the link domain, adding analytics tags, or specifying the link behavior.
How can I track user engagement with Dynamic Links?
You can track user engagement with Dynamic Links by using Firebase Analytics, which provides detailed metrics on link clicks, app installs, and app opens.
Can I use Dynamic Links to share content with other users?
Yes, you can use Dynamic Links to share content with other users by creating links that point to specific content within your app, such as a product page or a news article.
Are there any limitations or restrictions on using Dynamic Links?
Yes, there are some limitations and restrictions on using Dynamic Links, such as maximum link length, link expiration, and domain verification requirements. It’s important to review the Firebase Dynamic Links documentation for more details on these limitations.
Can I test Dynamic Links before releasing my app?
Yes, you can test Dynamic Links by using Firebase Dynamic Links testing tools, such as the Dynamic Links Preview page or the Firebase Dynamic Links REST API.
Do I need to pay for using Dynamic Links in my app?
No, Firebase Dynamic Links are free to use and are included as part of the Firebase platform. However, some Firebase features, such as Analytics and Cloud Messaging, may have usage limits or require payment for usage beyond certain thresholds.
Hi! Mr DevGeek 🙂 I’ve watched your youtube video since few months ago and it’s very useful. Thank you very much always!!!!
Could you also explain how to handle background links? I’m having a problem to handle firebase dynamic links background links handling.
Glad to hear that. but I also explained it. Which part of the video you don’t understand
What will happen if the app is not installed? please guide
I already explain in the video and blog bro please check it