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,
});
}
});
}, []);
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]);
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] );
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With