Home > Back-end >  useEffect not updating on auth.currentUser change
useEffect not updating on auth.currentUser change

Time:02-08

I want to update my state whenever the user authentication state changes (in my navigation page):

import {auth} from '../firebase.js' // where auth is initialized with getAuth() from firebase/auth
const Navigation = () => {
    const [isAuthenticated, setIsAuthenticated] = useState(false);
    useEffect(()=>{
        console.log("Here"); // Gets logged on sign out but not on sign in
        setIsAuthenticated(Boolean(auth.currentUser));
    }, [auth.currentUser])
    return ({isAuthenticated ? <SomeComponent /> : <SomeComponent />})
}

firebase.js

import { getAuth } from "firebase/auth";
const auth = getAuth(firebaseApp);
export {auth}

Then in my login component I have the signing function which should be and is updating the value of auth.currentUser:

const signIn = ({ email, password }) => {
    signInWithEmailAndPassword(auth, email, password)
      .then((resp) => {
        console.log(auth.currentUser); // This is working, meaning auth.currentUser value has changed
      })
      .catch((err) => setFirebaseError(err));
};

This works and gets executed whenever I sign out, but doesn't execute when a user signs in and I can't figure out why.

I know that the auth.currentUser variable is being updated since I print it out in the sign in function, but for some reason the useEffect does not recognize this and does not fire?

CodePudding user response:

Using auth.currentUser won't work because it's more or less a global variable exposed by firebase which will not trigger any sort of an update in react.

What you should rather do is subscribe to on onAuthStateChanged which will trigger whenever user logs in or out, and then use that to toggle your isAuthenticated flag.

For firebase v9

import { useState } from "react";
import { getAuth, onAuthStateChanged } from "firebase/auth";

const [isAuthenticated, setIsAuthenticated] = useState(false);

useEffect(() => {
  const auth = getAuth();

  const listener = onAuthStateChanged(auth, async (user) => {
    setIsAuthenticated(!!user);
  });

  return () => {
    listener();
  };
}, []);

For firebase v8

import { useState } from "react";
import firebase from "firebase";

const [isAuthenticated, setIsAuthenticated] = useState(false);

useEffect(() => {
  const listener = firebase.auth().onAuthStateChanged(auth, async (user) => {
    setIsAuthenticated(!!user);
  });

  return () => {
    listener();
  };
}, []);

Or even better, you can check out react-firebase-hooks or reactfire which provide a pretty nice set of hooks on top of firebase JS SDK.

  •  Tags:  
  • Related