Search code examples
firebasereact-nativeexpofirebase-dynamic-links

Firebase Dynamic Links doesn't navigate to deep link on iOS


Using Firebase Dynamic Links in a Managed Workflow Expo app directs to the correct deep link in the app on Android, but on iOS only opens the app in either whatever page was last open or the homepage.

app.config.js

ios: {
    associatedDomains: [
      'applinks:*.myapp.web.app',
      'applinks:myapp.web.app',
      'applinks:*.myapp.page.link',
      'applinks:myapp.page.link',
    ],
},

AppNavigation.js

  const linking = {
    prefixes: [
      prefix,
      'https://myapp.web.app',
      'https://*.myapp.web.app',
    ],

The apple-app-site-association file stored on myapp.web.app

{
    "applinks": {
        "apps": [],
        "details": [
            {
                "appID": "1234567890.com.my.app",
                "paths": [ "*" ]
            } 
        ]
    }
}

The Dynamic Link is generated using REST API with the following payload:

    const payload = {
      dynamicLinkInfo: {
        domainUriPrefix: 'https://myapp.page.link',
        link: `https://myapp.web.app/${deepLink}`,
        androidInfo: {
          androidPackageName: com.my.app,
        },
        iosInfo: {
          iosBundleId: com.my.app,
          iosAppStoreId: 1234567890,
        },

The generated Dynamic Link opens the app and directs to the ${deepLink} on Android as expected, but not on iOS. This was tested in an app built with EAS built.


Solution

  • Ended up solving this myself. Dynamic Links get resolved (converted from short link to full link) automatically on Android, but on iOS this has to be done manually with dynamicLinks().resolveLink(url);

    After resolving, the link gets picked up by React Native Navigation and works like a normal deep link.

    Full code for Dynamic Links:

      const linking = {
        prefixes: [
          'https://myapp.page.link',
          'https://myapp.web.app',
        ],
    
        async getInitialURL() {
          // If the app was opened with a Firebase Dynamic Link
          const dynamicLink = await dynamicLinks().getInitialLink();
          if (dynamicLink) {
            const { url } = dynamicLink;
            const resolvedLink = await dynamicLinks().resolveLink(url);
            return resolvedLink.url;
          }
    
          // If the app was opened with any other link (sometimes the Dynamic Link also ends up here, so it needs to be resolved
          const initialUrl = await Linking.getInitialURL();
          if (initialUrl) {
            const resolvedLink = await dynamicLinks().resolveLink(initialUrl);
            return (resolvedLink) ? resolvedLink.url : initialUrl;
          }
        },
    
        subscribe(listener) {
          const handleDynamicLink = (dynamicLink) => {
            listener(dynamicLink.url);
          };
    
          // Listen to incoming links from deep linking
          const unsubscribeToDynamicLinks = dynamicLinks().onLink(handleDynamicLink);
    
          return () => {
            // Clean up the event listeners
            unsubscribeToDynamicLinks();
          };
        },
      };
    
    

    In my case I also had to install all 3 of the following libraries:

    "@react-native-firebase/analytics": "16.4.3",
    "@react-native-firebase/app": "16.4.3",
    "@react-native-firebase/dynamic-links": "16.4.3",