Reputation: 41
I'm learning React and Firestore currently and am a bit stuck. I'm trying to retrieve a users name from a firestore collection by searching their uid.
The following code is executed in a map of 'lessons' to create a list.
{lesson.post_author && findName(lesson.post_author)}
The following code is the findName function.
let findName = uid => {
firebase.firestore().collection("users")
.where('uid', '==', uid)
.get()
.then(querySnapshot => {
console.log(querySnapshot.docs[0].data().name);
});
};
Currently, the findName function will console log all of the names to the console successfully. I've altered the code to be able to console log outside of the firestore call, but that returns a promise pending in console.
The goal of the code is to return the name rather then the uid in the list.
Any help would be much appreciated. Thank you!
Upvotes: 4
Views: 3641
Reputation: 598728
As others have explained, you can't return that value, since it's loaded from Firestore asynchronously. By the time your return
runs, the data hasn't loaded yet.
In React you handle this by putting the data in the component's state, and using it from there. If you do this, your render method can simply pick it up from the state, with something like:
{lesson.post_author && findName(lesson.post_author_name)}
(the above assumes that lesson
indirectly comes from the state.
It's a bit easier if we pretend there's only one lesson, and you have these values straight in the state:
{state.post_author && findName(state.post_author_name)}
Now I'll assume you already have the post_author
and you just need to look up the author's name. That means that somewhere in/after componentDidMount
you'll load the additional data and add it to the state:
componentDidMount() {
firebase.firestore().collection("users")
.where('uid', '==', this.state.uid)
.get()
.then(querySnapshot => {
this.setState({ post_user_name: querySnapshot.docs[0].data().name });
});
}
Now the loading of the data still happens asynchronously, so the call to setState()
happens some time after componentDidMount
has completed. But React is aware that changing the state may require a refresh of the component, so it responds to the call to setState()
by rerendering it.
Note that I'd highly recommend using each user's UID as the ID of the documents in users
. That way you don't need a query and can just do a directly lookup:
componentDidMount() {
firebase.firestore().collection("users")
.doc(this.state.uid)
.get()
.then(doc => {
this.setState({ post_user_name: doc.data().name });
});
}
Upvotes: 2
Reputation: 18555
I'm trying to retrieve a users name from a firestore collection by searching their uid.
This is accomplished by using the asyncronous .get
method on a Firestore reference. In your case, you probably have a users
collection of firebase.auth().currentUser.uid
named documents.
var userRef = firebase.firestore().collection('users').doc(users.uid);
userRef.get().then(function(doc) {
if (doc.exists) {
console.log("Users first name is:", doc.data().firstName);
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
}
}).catch(function(error) {
console.log("Error getting document:", error);
});
Upvotes: 1