Search code examples
react-nativeexporeact-native-deep-linking

React native expo app: deeplinking back into the app


I'm a react native beginner, I created the app with latest versions of react-native and expo. The app starts on iPhone and android with expo go and I can start a webbrowser on a button click. The webbrowser shows my companie's login page and after successfull login the user should be redirected into the app at a specific screen with a value that I need in my app to continue (value "myCode" in the code snippet below).

But the deeplink actually opens a new instance of my app (downloads the bundle again from expo server), instead of just bringing the already running app to the foreground. When I then start the login process again, the deeplink opens my app without downloading the app again but immediately crashes when I try to handle the redirect with the exception: "Can't find variable: Constants". I don't really understand this error and would like to get help with this. If you know how to use Linking in react-native you probably can help me.

I tried these deeplinks. They are called from my companies login page to send the user back to the app:

exp://127.0.0.1:19000/success?code={mycode}

exp://fa-p2b.<myExpoUser>.test.exp.direct:80/success?code={mycode}

The localhost link worked even without downloading the bundle again at the first time the user finishes the login. But it still crashed with the same warning.

Here is the code that I use to handle the redirect back into the app:

export default class StartScreen extends React.Component {
    state = {
        redirectData: null,
    };

    render() {
        return (
            <TouchableOpacity onPress={_openBrowserAsync}>
                    <Image
                        source={require('../assets/button.png')}
                        style={{ width: 200, height: 100 }}
                    />
                </TouchableOpacity>
        );
    }
};

_openBrowserAsync = async () => {
    try {
        this._addLinkingListener();
        let result = await WebBrowser.openBrowserAsync(
            `https://mycompany.com/login`
        );

        if (Constants.platform.ios) {
            this._removeLinkingListener();
        }

        this.setState({ result });
    } catch (error) {
        alert(error);
        console.log(error);
    }
};

_handleRedirect = (event) => {
    alert("handle redirect")
    alert(event.url)
    alert("passed eventurl")
    if (Constants.platform.ios) {
        WebBrowser.dismissBrowser();
        alert("dismissedBrowser")
    } else {
        alert("_removeLinkingListener")
        this._removeLinkingListener();
        alert("_removeLinkingListener")
    }
    alert("parse")
    let data = Linking.parse(event.url);
    alert("parse")
    this.setState({ redirectData: data });
    alert("setState")
};

_addLinkingListener = () => {
    Linking.addEventListener("url", this._handleRedirect);
};

_removeLinkingListener = () => {
    Linking.removeEventListener("url", this._handleRedirect);
};

_maybeRenderRedirectData = () => {
    if (!this.state.redirectData) {
        return;
    }

    return (
        <Text style={{ marginTop: 30 }}>
            {JSON.stringify(this.state.redirectData)}
        </Text>
    );
};

After the user logged in the function _handleRedirect gets called, I see the first alert from alert("handle redirect") But then it crashes with Can't find variable: Constants

The code is basically taken from here: https://github.com/expo/examples/blob/master/with-webbrowser-redirect/App.js


Solution

  • An import was missing:

    import Constants from 'expo-constants';
    

    -> solved the Constants warning. (I'm not used to programming languages that compile even if an import is missing, that's why I got stuck on this easy thing) After that the deeplink also worked.