Deep linking launches the app, but handles the external url wrongly

435 Views Asked by At

I am developing an React Native project, using React-Navigation v5.

I now try to implement deep linking feature. I followed the official instruction set up deep linking successfully (I mean the app is launched by custom url scheme). Next I need to handle the external link, my issue comes at this point.

To handle external link in my react-native project, I also followed the instruction configure links.

I defined a linking.js in my project:

const config = {
  screens: {
    // I explained why I nest FooScreen like this if you continue reading

    FeatureFlow: {
      SubfeatureFlow: {
        FooScreen: {
          path: 'foo/:myId',
        },
      },
    },
  },
};

const linking = {
  prefixes: ['myapp://mobile'],
  config,
};

export default linking;

Then, in my NavigationContainer, I use the linking as below:

return (
    <NavigationContainer
      linking={linking}
      ...
     >
      <MainFlow />
     </NavigationContainer>

As you can see above, three things worth a notice:

  1. in linking.js, inside config I specified that the path e.g. foo/123 should open screen FooScreen.

  2. The FooScreen is a nested screen.

  3. NavigationContainer contains a component called MainFlow.

To illustrated how FooScreen is nested in navigation hierarchy, let's start with MainFlow, which looks like this:

const MainFlow = ({navigation}) => {
  const Drawer = createDrawerNavigator();
  return (
    <Drawer.Navigator
      ...>
      <Drawer.Screen name="FeatureFlow" component={MyFeatureFlow} />
      ...
    </Drawer.Navigator>
  );
};

As you can see, MainFlow is a DrawerNavigator which hosts a screen named FeatureFlow refers to component MyFeatureFlow.

And MyFeatureFlow looks like this:

const MyFeatureFlow = ({navigation}) => {
  const FeatureStack = createStackNavigator();

  return (
    <FeatureStack.Navigator
      ...>
       <FeatureStack.Screen
         name="SubfeatureFlow"
         component={MySubfeatureFlow}/>
    </FeatureStack.Navigator>
  )

As you can see above, FeatureFlow is a stack navigator which hosts a screen named SubfeatureFlow, refers to component MySubfeatureFlow.

And MySubfeatureFlow is like:

const MySubfeatureFlow = ({navigation}) => {
  const SubfeatureStack = createStackNavigator();

  return (
    <SubfeatureStack.Navigator
      ...>
       <SubfeatureStack.Screen
          name="FooScreen"
          component={MyFooScreen}
    </SubfeatureStack.Navigator>
  )

As you can see above, MySubfeatureFlow is another stack navigator which hosts a screen named FooScreen refers to component MyFooScreen.

Now you understand why in linking.js configuration, the FooScreen is nested like that.

Then, I run my app on iOS simulator. The app launched. I killed the app on simulator.

Then, I run command npx uri-scheme open myapp://mobile/foo/123 --ios. (I also tried open mobile browser, type in url myapp://mobile/foo/123, same error as below)

I see on simulator, the app is launched by the command, which means my deep linking is set up. However, handling external link to open FooScreen fails, I end up with the following error:

enter image description here

The error tells me the navigation payload tries to treat 123 as screen, and the app treat foo as name of the screen in my project. I completely don't understand why it is. Is there something wrong with my linking configuration?

0

There are 0 best solutions below