Opening a dynamic link from a WebView inside React native App

Viewed 3070

I have a requirement to open an App screen using user selections on a website, where when user select an item it should openup the relevant page in the Mobile App. But the website should be loaded inside a webview within the same APP. Here I used Firebase dynamic links to manage this navigation.

I can open up the website from chrome browser in the emulator and open up the App navigated to exact page as required. But when I click the same component from the webview within the app it throws up the following error and App wont open up the page that the firebase dynamic link should open up as in the first case of the chrome browser.

Can't open url: intent://example.page.link/getapp#Intent;package=com.google.android.gms;action=com.google.firebase.dynamiclinks.VIEW_DYNAMIC_LINK;scheme=https;S.browser_fallback_url=https://play.google.com/store/apps/details%3Fid%3Dcom.ubercab;end;

My implementation is as follows,

WebApp

App.js

function App() {  

  return (

    <div>
      <Button variant="primary">
        Open this in your App
      </Button>
      <Banner url={"https://testingapp.page.link/getapp"}/>
    <Banner url={"https://testingapp.page.link/getapp"}/>
    <Banner url={"https://testingapp.page.link/getapp"}/>
    <Banner url={"https://testingapp.page.link/getapp"}/>
    </div>

  );
}

Banner.js

const Banner=(props)=>{
    const classes = useStyles();
    const [expanded, setExpanded] = React.useState(false);

    const styles = {
        cardAction: {
            display: 'block',
            textAlign: 'initial',
            height: '100%'
        }
    }



  return (
      <div onClick={() => window.open(props.url, "_blank")}>
          <Card className={classes.root}>
              <CardMedia
                  className={classes.media}
                  image= {banner}
                  title="Offer"
              />
          </Card>
      </div>

  );
        };

export default Banner;

On the Mobile App side:

App.jsx

import React, { useEffect } from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import dynamicLinks from '@react-native-firebase/dynamic-links';
import { WebView } from 'react-native-webview';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
function DetailsScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Details Screen</Text>
    </View>
  );
}

function HomeScreen({ navigation }) {
  async function buildLink() {
    console.log('building link');
    const link = await dynamicLinks().buildLink({
      link: 'https://invertase.io',
      // domainUriPrefix is created in your firebase console
      domainUriPrefix: 'https://testingapp.page.link',
      // optional set up which updates firebase analytics campaign
      // "banner". This also needs setting up before hand
      analytics: {
        campaign: 'banner',
      },
    });

    return link;
  }


  const handleDynamicLink = link => {
    // Handle dynamic link inside your own application
    console.log('Received URfffL:' + link.url);
    if (link.url === 'https://example.com/packageview') {
      console.log('hit package view');
      navigation.push('packageview');
    }
  };

  useEffect(() => {
    const unsubscribe = dynamicLinks().onLink(handleDynamicLink);
    // When the is component unmounted, remove the listener

    dynamicLinks()
      .getInitialLink()
      .then(link => {
        console.log('Received URL:' + link.url);
        if (link.url === 'https://example.com/packageview') {
          console.log('hit package view');
          navigation.push('packageview');
        }
      });


    return () => unsubscribe();


  }, []);
  return (   
      <WebView source={{ uri: 'http://10.0.2.2:3000/' }}/>   
  );
}


export default function App() {



  const Stack = createStackNavigator();

    return (
      <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="packageview" component={DetailsScreen} />
      </Stack.Navigator>
    </NavigationContainer>
    );

}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

Do anyone have any experience in anything related to this? On what's going wrong in here?

2 Answers

There is a solution, But more like a work around so it seems like webview blocking up requests with "intent://" head, as a solution "intent://" can be added to whitelist of the WebView. check the code below,

 <WebView      
      originWhitelist={['intent://']}
      source={{ uri: 'http://10.0.2.2:3000/' }}/>   

But the user experience might not be that great as this makes the URL to be opened from the web browser and web browser will the one doing the naigation to the page inside the app.

Hey for me this worked . add your dynamic link in webview orginWhitlelist without https/http add intent:// too

 <WebView
  source={{ uri: redirect_url }}
  originWhitelist={["intent://*", "applink.page.link/back"]}
/>

then follow https://rnfirebase.io/dynamic-links/usage documentication to Listen for Dynamic Links

make sure to select Open the deep link in your Android App for android and Open the deep link in your Apple app for ios while creating dynamic link in firbase

Related