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


#1

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”


#2

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


#3

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.


#4

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.


closed #5

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