I was trying to fetch from two different collection but I got a weird situation. First, I want to fetch a userID from posts collection. Then with that userID, I want to fetch data from users collection.
So, when I fetch from only the posts collection, print command works perfectly fine and prints the userID.
But when I add the users fetch statement that I showed in the code below it doesn't fetch it and shows an empty string (''), and users collection sends an error because I couldn't search the userID. What am I missing here?
class _ProductDetail extends State<ProductDetail> {
String getTitle = '';
String getLocation = '';
String getPrice = '';
String getImage = '';
String getUniversity = '';
String getProfileImage = '';
String getUserName = '';
String getSellerUserID = '';
@override
Widget build(BuildContext context) {
FirebaseFirestore.instance
.collection('posts')
.doc(widget.postID)
.get()
.then((incomingData) {
setState(() {
getTitle = incomingData.data()!['title'];
getPrice = incomingData.data()!['price'];
getImage = incomingData.data()!['postImage'];
});
});
FirebaseFirestore.instance
.collection('posts')
.doc(widget.postID)
.get()
.then((incomingData) {
setState(() {
getSellerUserID = incomingData.data()!['userID'];
});
});
print(getSellerUserID); //statement that will print the userID
//////////////////////IF I DELETE THIS SECTION, IT PRINTS THE USER ID//////////////////
FirebaseFirestore.instance
.collection('users')
.doc(getSellerUserID)
.get()
.then((incomingData) {
setState(() {
getUserName = incomingData.data()!['username'];
getProfileImage = incomingData.data()!['profileImage'];
getUniversity = incomingData.data()!['university'];
getLocation = incomingData.data()!['location'];
});
});
///////////////////////////////////////////////////////////////////////////////////////////////
return Scaffold(
....... rest of the code
CodePudding user response:
Since data is loaded from Firestore asynchronously, the code inside your then blocks is called (way) later then the line after the call to get().
To see this most easily, add some logging like this:
print("Before calling Firestore")
FirebaseFirestore.instance
.collection('posts')
.doc(widget.postID)
.get()
.then((incomingData) {
print("Got data")
});
print("Before calling Firestore")
If you run this code, it'll print:
Before calling Firestore
After calling Firestore
Got data
This is probably not the order you expected, but does explain why your next load from the database doesn't work: the getSellerUserID = incomingData.data()!['userID'] line hasn't been run yet by that time.
For this reason: any code that needs the data from Firestore, needs to be inside the then (or onSnapshot) handler, be called from there, or be otherwise synchronized.
So the simplest fix is to move the next database call into the `then:
FirebaseFirestore.instance
.collection('posts')
.doc(widget.postID)
.get()
.then((incomingData) {
var sellerUserID = incomingData.data()!['userID'];
setState(() {
getSellerUserID = sellerUserID;
});
print(sellerUserID);
FirebaseFirestore.instance
.collection('users')
.doc(sellerUserID)
.get()
.then((incomingData) {
setState(() {
getUserName = incomingData.data()!['username'];
getProfileImage = incomingData.data()!['profileImage'];
getUniversity = incomingData.data()!['university'];
getLocation = incomingData.data()!['location'];
});
});
});
