menu
announcement

Spectrum is now read-only. Learn more about the decision in our official announcement.

Divjoy

The ⚛️ React codebase generator.

Channels
Team

Component renders before getting the uid value from the useAuth() hook

December 20, 2020 at 11:08pm

Component renders before getting the uid value from the useAuth() hook

December 20, 2020 at 11:08pm (Edited 2 years ago)
I have the following setup to get a collection of documents from Firestore,I have the following setup to get a collection of documents from Firestore which works when tested with a hardcoded user id. However, when dynamically fetching the uid from the useAuth() I always receive a "Cannot read property uid of null" exception. I think that it may be that the uid is not retrieved from the useAuth in time for the first render, but I am not sure. Does anybody know how I can fix this?
const [loading, setLoading] = useState(true); // Set loading to true on component mount
const [posts, setPosts] = useState([]); // Initial empty array of posts
const userId = useAuth().user.uid; // Error occurs here on first render, "cannot read property uid of undefined"
useEffect(() => {
const subscriber = firestore()
.collection('feeds')
.doc(userId)
.collection('posts')
.onSnapshot((querySnapshot) => {
const postData = [];
querySnapshot.forEach((documentSnapshot) => {
firestore()
.collection('posts')
.doc(documentSnapshot.id)
.get()
.then((postDoc) => {
postData.push({
...postDoc.data(),
id: postDoc.id,
});
})
.then(() => setPosts(postData))
.then(() => setLoading(false))
.catch((err) => console.log(err));
});
});
// Unsubscribe from events when no longer in use
return () => subscriber();
}, [userId]);

December 21, 2020 at 2:11am
useAuth().user will be null initially while it's still loading from Firebase, then it will either be false if the user is not authenticated or it will be the user's data object. The easiest way to manage this is with the requireAuth higher order component (in src/util/auth.js). When exporting your page component you'd just wrap with this function like so:
export default requireAuth(SomePage);
Then it will just show a loading indicator until it has the user data and if the user is not authenticated it will redirect to /auth/signup.
Also check out how we manage Firestore data fetching with the hooks we give you in src/util/db.js. You may want to create another hook in there, like usePosts, that utilizes the useQuery hook to handle this for you.
Another nice thing about the useQuery hook is that you can pass undefined to it if you don't yet have the data you need (such as the user's uid). That would enable you to handle the loading state yourself (instead of utilizing requireAuth) and simply pass undefined to the data fetching hook until you have a uid from useAuth.
Edited
like-fill
1

December 21, 2020 at 4:55pm
(gabe-ragland) thank you very much, I appreciate your dedication to the divjoy users! I was able to solve my issue with your feedback.
like-fill
1