QuickStart: React Native Mobile Integration

📘

Recommendation

If you are integrating Connect into a mobile app, we recommend using the Hosted App experience for simplicity and to reduce your dependencies.

We suggest that you render Connect inside of a webview. The way to do so is by obtaining a session or id token, then opening the following URL: https://hapi-connect.humanapi.co?token=<hapi-session/id-token>

Interactivity Between Webview and your application

The connect application emits messages to its parent (in this case, your app) in the form of:
window.parent.postMessage("hapi-connect-<EVENT_NAME>", "*");

Where <EVENT_NAME> can be any of the following:

  • connect-source: This event will be fired after a source has been successfully connected
  • disconnect-source: This event will be fired after a source has been disconnected
  • close: This event will be fired when the Connect window is closed or when the "I'm finished connecting sources" button is clicked, regardless of whether sources were connected or not
  • error: This event fires in case there's an error with connect e.g. an incorrect token was shown
  • open-url: This event fires when connecting to wellness source is initiated

The idea of these messages is that the webview can interact with your application and you can choose which actions to take depending on each message.

Connecting sources with OAuth

Connecting sources with OAauth in a web browser would normally open a pop-up window for your users to authenticate in. In a mobile context this type of interaction is not possible. It is recommended to override the window.open function to instead post a message. This way, you can listen for these messages and navigate to a follow-up webview where the user can authenticate. Check the link in the section titled "React Native example" for a full working example.

<WebView
    injectedJavaScriptBeforeContentLoaded={`
      window.open = (url) => {
        window.ReactNativeWebView.postMessage(JSON.stringify({ type: 'hapi-open-url', url: url }));
        return true;
      }
    `}
    onMessage={async event => {
        const { type } = JSON.parse(event.nativeEvent.data);

        if (type === 'hapi-open-url') {
            // navigate to another webview where users can authenticate
        }
    }
/>

Links to external pages

The Connect page has different links that, by default, would open in the same webview. This makes navigation not straightforward since you lose the references.

We suggest those messages to be intercepted by your application. This allows you to decide how to manage those interactions. For example, external links can be opened in a browser.

import { Linking } from "react-native";

const onNavStateChange = newNavState => {
    const { url } = newNavState;
    if (!url.includes('humanapi.co')) {
        webview.current.stopLoading();
        Linking.openURL(url);
    }
};

<WebView
    onNavigationStateChange={onNavStateChange}
/>

React Native example

Inject an event listener that will get the message and post it directly to the React Native WebView. Compose a Connect URL by specifying a token query parameter containing a Session or ID Token.

You may also specify optional query parameters mode, segment, and pinnedProviders, for more information, take a look at Customize your Connect integration.

<WebView
    source={{
        uri: `https://hapi-connect.humanapi.co?token=${TOKEN}&mode=auth`,
    }}
    onLoadEnd={() => {
        webview.current.injectJavaScript(`
            addEventListener('message', function(e) {
                window.ReactNativeWebView.postMessage(JSON.stringify(e.data));
            });
        `);
    }}
    onMessage={async event => {
        console.log(event.nativeEvent.data);
    }}
/>

📘

Working sample

You can see a full working sample here. To test it live, you will need to provide an session token in the file ConnectScreen.js line 6.

📘

Helpful docs

Webview Communication between JS and React Native