I make sign up system and managing user information.
When sign-up, users are required to write user name, and it's stored in firestore.
User data are stored like this;
And trying to get userName
with the code;
CollectionReference users = FirebaseFirestore.instance.collection('users');
return FutureBuilder<DocumentSnapshot>(
future: users.doc(FirebaseAuth.instance.currentUser!.uid).get(),
builder:
(BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (snapshot.hasError) {
return Text("Something went wrong");
}
print("${!snapshot.hasData} ${!snapshot.data!.exists}"); // always "false true"
if (!snapshot.hasData && !snapshot.data!.exists) {
return Text("Document does not exist");
}
if (snapshot.connectionState == ConnectionState.done) {
Map<String, dynamic> data =
snapshot.data!.data() as Map<String, dynamic>;
return Text("User Name: ${data['userName']}");
}
return const CircularProgressIndicator();
},
);
However always return Text("Document does not exist");
is called, and userName
is not displayed.
Why doesn't userName
returned? I searched for a misspelling but couldn't find it.
This issue has taken a lot of time today. Thank you.
CodePudding user response:
Miss to use !
before snapshot.hasData
if (!snapshot.hasData && !snapshot.data!.exists) {
return Text("Document does not exist");
}
CodePudding user response:
The snapshot.data
that you are referring to is the AsyncSnapshot
that is used to monitor the status of the asynchronous operation. Its hasData
becomes true when the asynchronous operation has completed: so when it is done reading the DocumentSnapshot
from the database.
To detect whether the DocumentSnapshot
actually exists, you need to check its exists
property.
A quick summary of common statuses:
Object.property | Value | Explanation |
---|---|---|
AsyncSnapshot.hasData |
false |
the asynchronous operation has either not yet completed, or did not result in a DocumentSnapshot (for example: if there was a network error). Calling snapshot.data will result in an error message. |
AsyncSnapshot.hasData |
true |
the asynchronous operation has completed and you can safely call snapshot.data on it to get the DocumentSnapshot . |
DocumentSnapshot.exists |
false |
the document you requested does not exist, and calling document.data on the snapshot will result in an error. |
DocumentSnapshot.exists |
true |
the document you requested exists, and you can access its data. |
So your !snapshot.hasData
will be false once the AsyncSnapshot
is done loading the DocumentSnapshot
. To determine whether the document actually exists, use snapshot.hasData && snapshot.data!.exists
.
I also recommend checking out my explanation here of the various types of snapshots in Flutter code: What is the difference between existing types of snapshots in Firebase?