I'm trying to enable deeplink in my React Native project, and have it working for all use-cases where the deeplink opens the app from the background, not from the first load. I believe the issue is that my path that I am deep-linking, is not available until after the "loading screen" has gone away.
For example I have this setup as my RootStack.Navigator
<RootStack.Navigator
detachInactiveScreens={false}
headerMode="none"
initialRouteName={"AppTabsScreen"}
screenOptions={{ animationEnabled: false }}
mode="modal"
>
{isLoading ? (
<RootStack.Screen
name="LoadingScreen"
component={LoadingScreen}
options={{ animationEnabled: true }}
/>
) : user ? (
<RootStack.Screen name="AppTabsScreen" component={AppTabsScreen} />
) : (
<RootStack.Screen name="AuthStackScreen" component={AuthStackScreen} />
)}
...
And my linking config as:
const deepLinksConf = {
screens: {
AppTabsScreen: {
screens: {
initialRouteName: "Activity",
Activity: {
screens: {
Activity: "activity",
Details: "workout/:userId/:id",
},
},
Goals: {
screens: {
Goals: "goal",
GoalDetail: "goal/:id",
},
},
Settings: "settings",
Profile: "profile",
},
},
}
};
In my getInitialURL() function, I get the URL correctly, but I believe the path is already on the LoadingScreen, and not the AppTabsScreen, which causes it not to fire. Is there anyway around this situation? How can I delay the deeplink to wait until the AppTabScreen is present to process the link? This works fine when the app is the fore or background, but never at first start.
....
async getInitialURL() {
console.log("fired");
// Check if app was opened from a deep link
const url = await Linking.getInitialURL();
console.log("deeplinking");
console.log(url);
if (url != null) {
console.log("just returning");
return url;
}
// Check if there is an initial firebase notification
const message = await messaging().getInitialNotification();
// Get deep link from data
// if this is undefined, the app will open the default/home page
return messsage.data?.link;
},
I am using react-navigation, and my main navigation controller is as follows:
<NavigationContainer
linking={linking}
theme={scheme === "dark" ? DarkTheme : DefaultTheme}
ref={navigationRef}
onReady={() => {
if (navigationRef.current) {
routeNameRef.current = navigationRef?.current.getCurrentRoute().name;
}
}}
onStateChange={async () => {
const previousRouteName = routeNameRef.current;
const currentRouteName = navigationRef?.current.getCurrentRoute().name;
if (previousRouteName !== currentRouteName) {
await analytics().logScreenView({
screen_name: currentRouteName,
screen_class: currentRouteName,
});
}
// Save the current route name for later comparision
routeNameRef.current = currentRouteName;
}}
>
<FlashMessage position="top" />
<RootStackScreen />
</NavigationContainer>