Expo.Google.logInAsync causes triple navigation/component mounting on next screen

Hello,

When I sign in (using Expo/firebase/Google login), after the Google login succeeds, something about the React Native lifecycle (I think) causes the application to fire 3 “navigates” to the home screen (the new screen slides in 3 times in a row). I’m using React Navigation and I am not sure if I am using the async/await keywords correctly in my logInWithGoogleAsync() function. I have a feeling that something about these asynchronous functions are causing multiple firings.

Any help is much appreciated, please let me know if I can provide more information.

Here is my app.js

const Application = StackNavigator({
    Login: { screen: Login,
        navigationOptions: {
                title: 'Login',
        }
    },
    Home: { screen: Home,
        navigationOptions: {
           title: 'Home'
       }
    },
});
export default class App extends React.Component {
    render() {
        return (
            <Application/>
        );
    }
}

Relevant portion of Login.js

export default class Login extends React.Component {

    constructor(props){
        super(props)
        this.state = {
            isLoggingIn: true,
        }
    }

    componentDidMount() {

        const firebaseConfig = {
           //firebase config stuff
        }

        if (!firebase.apps.length) {
            firebase.initializeApp(firebaseConfig);
        }

        firebase.auth().onAuthStateChanged((user) => {
            if(user){
                this.props.navigation.navigate('Home');
                return;
            }
            else{
                this.setState({ isLoggingIn: false });
                return;
            }
        });
    }

logInWithGoogleAsync = async (navigate) => {
        try {
            await this.setState({ isLoggingIn: true });
            //get Google token via Expo
            const result = await Expo.Google.logInAsync({
                iosClientId: 'CLIENT_ID',
                iosStandaloneAppClientId: 'CLIENT_ID',
                scopes: ['profile', 'email'],
            });
            if (result.type === 'success') {
                console.log('google token acquired');
                //Build Firebase credential with the Google token
                const credential = await firebase.auth.GoogleAuthProvider.credential(result.idToken, result.accessToken);
                const user = await firebase.auth().signInWithCredential(credential);
                navigate('Home');
                return;
            }
            //login fails
            else {
                return {cancelled: true};
            }
        }
        catch(error) {
            await this.setState({ isLoggingIn: false });
            return {error: true};
        }
    }
}

Relevant portion of Home.js
During testing i placed log statements in componentDidMount() and it logged multiple times.

export default class Home extends React.Component {

    constructor(props){
        super(props)
        this.state = {
            latitude: null,
            longitude: null,
            locationError: null,
        }
    }

    componentDidMount() {
        navigator.geolocation.getCurrentPosition(
            (position) => {
                this.setState({
                    latitude: position.coords.latitude,
                    longitude: position.coords.longitude,
                    error: null,
                });
            },
            (error) => this.setState({ error: error.message }),
            { enableHighAccuracy: true, });
    }
}

Using:

“react”: “16.3.0-alpha.1”,
“react-native”: “0.54.0”,
“react-navigation”: “^1.5.11”

hi @daveyjonez, there are multiple reasons why componentDidMount will be called more than once – prop keys changing or creation/deletion of the components will also trigger it: https://stackoverflow.com/questions/39974210/why-componentdidmount-gets-called-multiple-times-in-react-js-redux

But since there is no navgiate() in the Home.js componentDidMount(), why am I seeing multiple navigations/animations?

The point I’m trying to get at is: Something in Login.js must be triggering multiple navigates, thus causing the multiple componentDidMount() calls.

hey @daveyjonez,

It could be logInWithGoogleAsync being triggered multiple times wherever its called, or

            if(user){
                this.props.navigation.navigate('Home');
                return;
            }

could be the culprit if your Login componentDidMount is getting triggered more than once.

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.