Search code examples
reactjsreact-nativegoogle-cloud-firestorereact-hooksfirebase-authentication

React Native useEffect() not triggered with firebase and onAuthStateChanged


I have an app using react native and firebase. In the App.js I have a useEffect wrapper observing onAuthStateChanged to display either the registration/login or app views if the user object is present.

In the registrationView I have a

const [userData, setUserData] = useState(null);

const register = useCallback(async () => {
    try{
      await createUserWithEmailAndPassword(auth, email, password)
        .then((registerresponse) => {          
            const user = registerresponse.user.uid;
            setUserData(user);
        })

    } catch(error) {

      /..some error coding.../

      setError(msg);

      console.error(error.message);
    }
  }, [email, password, error, userData]);

And a callback useEffect to do some database work:

useEffect(() => {
    if (userData) {
      
      try{

        setDoc(doc(db, "user", userData), {
          username: username,
          country: country
        });

        console.log("User Registered");

      }catch(error) {
        console.error(error.message);
      }

    }
  }, [userData]);

The issue I figured out is that because as I have the observer on the App.js that changes the View immediately after the user object is present, the useEffect on the registrationView is never fired. The app immediately navigates to the home screen but database work is not done.

So basically the question is, how do I keep the onAuthStateChanged pending until the useEffect has been done. OR is there a better way to handle post registration work as middleware before route transition?


Solution

  • There is no way to delay the calling of your onAuthStateChanged callback.

    The idiomatic approach is to put all code that needs to run when the user has signed in into the onAuthStateChanged callback. So you'd call setUserData(user); from there, rather from from the createUserWithEmailAndPassword callback as you now do.