React Native Firebase Authentication with Hooks loses userState on app resume

I’m currently creating a React Native mobile application with Typescript.

The application uses the Firebase authentication with the Google OAuth Provider.

In order to use the username and some other details (retrieved from Firestore) I’m using a React Provider like shown in the following example:

import React, {useState, useEffect} from 'react';
import auth from '@react-native-firebase/auth';
import { GoogleSignin } from '@react-native-community/google-signin';
import firestore from '@react-native-firebase/firestore';

GoogleSignin.configure({
    webClientId: 'x.googleusercontent.com',
});

const getUserById = async (id: string) => {
    const admin = await firestore().collection("users").doc(id).collection("priv").doc("admin").get();
    const prot = await firestore().collection("users").doc(id).collection("priv").doc("protected").get();

    const jsonData = {
        admin: admin.data(),
        protected: prot.data(),
    };
    return jsonData;
}

const AuthContext = React.createContext({});

function AuthProvider(props: any) {

    const [user, setUser] = useState(auth().currentUser);
    const [details, setDetails] = useState({});
    const [initializing, setInitializing] = useState(true);

    const onAuthStateChanged = async (authUser: any) => {
        setUser(authUser);
        if (authUser !== null)
          refreshDetails();
    }

    const refreshDetails = async () => {
        const details = (await getUserById(user.uid));
        setDetails(details);
    }

    useEffect(() => {
        const subscriber = auth().onAuthStateChanged(onAuthStateChanged);
        return subscriber; // unsubscribe on unmount
    }, []);

    const loginWithGoogle = async () => {
        const { idToken } = await GoogleSignin.signIn();

        // Create a Google credential with the token
        const googleCredential = auth.GoogleAuthProvider.credential(idToken);

        // Sign-in the user with the credential
        return auth().signInWithCredential(googleCredential);
    }

    const logout = () => {
        auth()
            .signOut()
    }

    return (
        <AuthContext.Provider value={{user, loginWithGoogle, logout, refreshDetails, details, initializing}} {...props}></AuthContext.Provider>
    )
}

const useAuth = () => {
    const state = React.useContext(AuthContext);
    return {
        ...state,
    };
}

export {AuthProvider, useAuth};

As you can see in the example I’m using this useEffect method from React to subscribe to authentication changes.

Unfortunately if I close the app and reopen it again, this authentication change isn’t triggered so the user state isn’t set and I get a bunch of errors.

What would be the best practice in a scenario like this? I think I only need to trigger the onAuthStateChangeEvent when the app was started again.

Thanks for all help
IJustDev

47 thoughts on “React Native Firebase Authentication with Hooks loses userState on app resume”

  1. onAuthStateChanged function must be triggered when the app re-opens. However, it’s supposed to run asynchronously you have to implement the case user’s value is invalid.

    Reply

Leave a Comment