Reputation: 335
I am streaming a Document snapshot from Firestore, but snapshot.hasData returns true when there is nothing in the db. This causes my code to fail when try retrieve value out of the snapshot.
How do I fix this?
I tried print out snapshot.Data just got an Documentsnapshot instance. Also thought about provide initial data to the stream, but I do not know how to provide an empty DocumentSnapshot data type.
If I manually insert a record in to firestore, it works fine.
StreamBuilder<DocumentSnapshot>(
stream: Firestore.instance.collection('UserDetails').document(widget.uid).snapshots(),
builder: (context, snapshot){
if(snapshot.hasError){
widget._err = snapshot.error;
} else if (snapshot.connectionState == ConnectionState.waiting){
widget._loadingUserInfo = true;
} else if (snapshot.hasData){
nameController.text = snapshot.data['name'];
ageController.text = snapshot.data['age'];
introController.text = snapshot.data['intro'];
widget._loadingUserInfo = false;
}
)
I am trying to get user value from Firestore to populate their form if there is a value or user exists.
Now it just fails.
Upvotes: 1
Views: 5289
Reputation: 7919
The cause of the confusion is that Firestore returns a DocumentSnapshot
even when there is nothing in the database to return.
FutureBuilder<DocumentSnapshot>(
future: firestore
.document('collection/non_existant_document')
.get(),
builder: (BuildContext context,
AsyncSnapshot<DocumentSnapshot> snapshot) {
if (snapshot.hasData) {
print('Has Data');
}
}),
The above code returns an empty DocumentSnapshot
. However, since it returns DocumentSnapshot
in data
, hasData
evaluates to true.
To check if the DocumentSnapshot
contains data, use
if (snapshot.data?.exists ?? false) {}
Upvotes: 2
Reputation: 67
May be you can try checking if data is null with:
if (snapshot.data == '[]') then
In your case...
....
else if (snapshot.hasData && snapshot.data.toString() != '[]') then){
nameController.text = snapshot.data['name'];
ageController.text = snapshot.data['age'];
introController.text = snapshot.data['intro'];
widget._loadingUserInfo = false;
}
Took me an hour to figure this out...
Upvotes: 0
Reputation: 61
I've found that although print( snapshot.hasData );
gets true,
print( snapshot.data.documents.isEmpty );
and print( snapshot.data.exists );
get true as well..
hence, to solve my issue, I used:
if (!snapshot.hasData || snapshot.data.documents.isEmpty) //for QuerySnapshot
OR
if (!snapshot.hasData || !snapshot.data.exists) //for DocumentSnapshot
Upvotes: 6
Reputation: 2326
snapshot.hasData
will return true for an empty dataset, ie:
snapshot.data = []
Personally, I consider hasData
to mean "has a response".
Upvotes: 2
Reputation: 3894
Why don't you just add a validation?
Something like
if (snapshot.hasData && (snapshot.data == null) return SizedBox();
Also if you are retrieving a list you could check if data != null and snapshot.data.length == 0;
Upvotes: 0
Reputation: 277057
It is impossible for hasData
to return true
when there no data.
hasData
is nothing but a shorthand for:
snapshot.data != null
Which means that you do have data. But maybe not the data you want.
Upvotes: 0