Home > OS >  React doesn't call useEffect on firebase (v9) auth update
React doesn't call useEffect on firebase (v9) auth update

Time:02-08

I'm uploading a user profile image into firebase storage, then updating the photoURL value of the auth user with updateProfile(). After that I want the user to be updated without manually refreshing the page. I've been trying this for days now and the issue gets more weird every time I try to debug it.

The interesting thing is the user object seems to be already updated when I log it with console.log(currentUser) after the then promise of updateProfile() is fulfilled. So the new photoURL is already present in the currentUser object. But it seems to not call a state update or console.log("!!!!currentAuthUserUpdate", user);. So the user image wouldn't refresh in my page.

I even tried it with doing a useEffect with the currentUser as a dependency but it wasn't fired. Still, the currentUser object changed when logging it after updateProfile()

Updating the profile, UpdateUserImage.tsx:

import { useAuth } from "../../contexts/AuthContext";

const { currentUser } = useAuth();

// updating the user profile
updateProfile(currentUser, { photoURL })

AuthContext.tsx:

import { auth } from "./../firebase/firebase";

const [currentUser, setCurrentUser] = useState(null);

const auth = getAuth(app);

  useEffect(() => {
    const unsubscribe = auth.onAuthStateChanged((user) => {
      console.log("!!!!currentAuthUserUpdate", user);

      // I tried setting the user as a custom new object: const userData = { ...user };
      setCurrentUser(user);
    });
    return unsubscribe;
  }, []);

firebase.js

import { getAuth } from "firebase/auth";

// Initialize Firebase
const app = initializeApp(firebaseConfig);
const auth = getAuth(app);

export {
  auth
};

What I tried additionally: (But this wouldn't work as the user is already updated without a state refresh from react, so it's trying to replace the same object)

const reloadUser = async () => {
    try {
      const res = await currentUser.reload();
      const user = auth.currentUser;
      console.log("currentUser:", user);

      setCurrentUser(auth.currentUser);

      console.log("res", res);
    } catch (err) {
      console.log(err);
    }
  };

CodePudding user response:

setCurrentUser need to be passed as a dependency into the useEffect unless you pass setCurrentUser an updater function: setCurrentUser(()=>auth.currentUser)

The React docs dispute this though.

CodePudding user response:

it's not auth.onAuthStateChanged. You need to import onAuthStateChanged from 'firebase/auth'

import { getAuth, onAuthStateChanged } from "firebase/auth"
const auth = getAuth(); // leave getAuth empty if you only have one app

Then in your useEffect it should be

 onAuthStateChanged(auth, async (currentUser) => { ... }

CodePudding user response:

Using useStates are good for re-rendering components. However going into utilizing useRefs are best for updating the actual variable and will not cause a re-render of the component.

Declare it like:const currentUser = useRef(null)

Update it like: currentUser.current = updatedUserData

Use in code like: currentUser.current.photoURL

  •  Tags:  
  • Related