In a future builder, I use the following future that should return the number of documents (The collection stores "seen" event of an ad detailed view):
/// Stores and returns the document [id].
static Future<int> getCount({required String? adId}) {
if (adId == null) return Future<int>.value(0);
// = Actually store the document
final c = FirebaseFirestore.instance
.collection(collectionName)
.where("adId", isEqualTo: adId)
.snapshots()
.length;
return c;
}
The FutureBuilder
:
FutureBuilder(
future: ClassifiedAdSeen.getCount(adId: ad.id),
builder: (context, snapshot) {
if (snapshot.hasError) {
return const Icon(Icons.error);
} else if (!snapshot.hasData) {
return const CircularProgressIndicator();
}
final count = snapshot.data ?? "—";
return Text("$count");
}),
But it never hasData
nor hasError
, the spinner keeps on progressing.
Any idea Where the issue is, please?
[UPDATE]By fetching the documents, I get the completion and the count with no problem.
But fetching the documents is a waste of memory and bandwidth, isn’t it?
So what would be the best way of fetching only the document count?
/// Stores and returns the document [id].
static Future<int> getCount({required String? adId}) async {
if (adId == null) return 0;
// = Actually store the document
final c = await FirebaseFirestore.instance
.collection(collectionName)
.where("adId", isEqualTo: adId)
.get();
return c.size;
}
2
Answers
The
snapshots()
returns aStream
, since you said that you want just to get the number of the documents on your query, consider usingget()
, in addition that you need anasync/await
in your method, then return theQuerySnapshot
in yourFuture
method, then call the length on it’sdocs
property :FutureBuilder
:In your case, which is getting only the length of documents from your query, there is also a
count()
method that returns anAggregateQuery
, which you don’t get billed for, it returns only the length of the documents, nothing else.Give it a try: