Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Firebase ReactJS useEffect TypeError: Cannot read property 'uid' of null

I'm new to ReactJS and web-dev in general. I know this questions gets asked a lot and I've tried a number of different solutions but none of them seem to have fixed my problem. I have Firebase user authentication that creates a document under a "user" collection when someone creates an account. The document ID is identical to the UID. I'm trying to get the field values stored in the document (fname, lname). I believe the problem is that currentUser.uid isn't being retrieved by the time the component renders? Sorry if I have the terminology wrong.

Test.js

const [fname, setFname] = useState('');
const [lname, setLname] = useState('');
const auth = firebase.auth();
const db = firebaseApp.firestore();


    useEffect( () => {
        let uid = auth.currentUser.uid;

        if(auth){
            db.collection("user").doc(uid)
            .onSnapshot( snapshot => {
                setFname(snapshot.fname);
                setLname(snapshot.lname);
            })
        } else{

        };
    }, );
    return (
        <div className="test">
            <p>this is here</p>
            <p>{!auth ? "This is null" : fname}</p>
            
        </div>
    )

My understanding is that useEffect runs only after the component has mounted. The uid infrequently does get successfully retrieved, but only around once out of ten times.

I tried running onAuthStateChanged under App.js and passing uid down as a prop to Test.js but the same issues also kept occurring.

App.js

const [{}, dispatch] = useStateValue();
const [uid, setUID] = useState(null);

  useEffect(() => {
    // will only run once when the app component loads...
    auth.onAuthStateChanged((authUser) => {
      console.log("THE USER IS >>> ", authUser);
      console.log(uid)

      if (authUser) {
        // the user just logged in / the user was logged in
        dispatch({
          type: "SET_USER",
          user: authUser,
        });
        setUID(auth.currentUser.uid);
      } else {
        // the user is logged out
        dispatch({
          type: "SET_USER",
          user: null,
        });
      }
    });
  }, []);

like image 314
clavesoon Avatar asked Dec 18 '25 21:12

clavesoon


2 Answers

The error occurs because currentUser is undefined when this blocks is executed, so you need to wait for auth been updated.

Add auth as dependency in useEffect:

useEffect( () => {
    if(auth.currentUser){
        let uid = auth.currentUser.uid;

        db.collection("user").doc(uid)
        .onSnapshot( snapshot => {
            setFname(snapshot.fname);
            setLname(snapshot.lname);
        })
    } else{

    };
},[auth]);
like image 106
lissettdm Avatar answered Dec 20 '25 11:12

lissettdm


Try this:

    useEffect( () => {
        let uid = auth? .currentUser? .uid;

        if(auth){
            db.collection("user").doc(uid)
            .onSnapshot( snapshot => {
                setFname(snapshot.fname);
                setLname(snapshot.lname);
            })
        } else{

        };
    }, [auth] );
like image 35
crispengari Avatar answered Dec 20 '25 11:12

crispengari