flutterfirebasegoogle-cloud-firestore

flutter firestore await fore query snapshot stream return old value first, then update to new value


I'm using flutter with firestore database, trying to build a time range query for returning stream of data from firestore. the behavior I see is weird, I run the query, I get old query results, after couple of seconds, I get stream update with the new query results. I'm using await for for the purpose of waiting the stream to finish.

here is my query snapshots streaming - repository code:

Stream<QuerySnapshot> packagesColStream = query.snapshots();
print('built query - sent');
await for (QuerySnapshot e in packagesColStream) {
    print('awaiting for stream');
    List<Package> packagesList = [];
    for (var doc in e.docs) {
      var data = doc.data() as Map<String, dynamic>;
      Package package = Package.fromDocument(data);
      if (filterFunction != null) {
        if (!filterFunction(package)) {
          continue;
        }
      }
      packagesList.add(package);
    }
    print('built list - yielding');
    yield packagesList;
}

the code that handles the yield:

print('on GetStoreGroupingPackagesEvent');
Stream<List<Package>> packagesStream = packagesRepo.getPackagesStream(
      event.fromDate,
      event.endDate,
);
await for (List<Package> packagesList in packagesStream) {
print('got stream from repository');
var groupedStores =
          groupBy(packagesList, (element) => element.storeID);
List<PackageGroup> packagesGroups = groupedStores.values
          .map(
            (e) => PackageGroup(
              groupKey: Store(
                id: e[0].storeID,
                name: e[0].storeName,
                // proprietorshipNumber: e[0].storePS,
                phoneNumber: e[0].ownerPhone,
                address: '',
                email: '',
                imageURL: '',
              ),
              packagesList: e,
            ),
          )
          .toList();
print('returning grouped by stream');
emit(PackagesGroupingState.loaded(packageGroupsList: packagesGroups));
 

the printout:

applyting  filter
on GetStoreGroupingPackagesEvent
built query - sent
state is PackagesGroupingStatus.loading
awaiting for stream
built list - yielding
got stream from repository
returning grouped by stream
state is PackagesGroupingStatus.loaded
awaiting for stream
built list - yielding
got stream from repository
returning grouped by stream
state is PackagesGroupingStatus.loaded 

please notice, that the "awaiting for stream is printed twice, the first one returned for me the old data I had, the second one had the correct data.

Why such behavior happen ? why await for is not really waiting for stream ?


Solution

  • Apparently, what is happening actually is that firestore firstly fetch the data from cache that fits the query, and only then fetch the rest of the data from firestore.

    Hence, if the new query has only more data on top of the original query, then it only stream the rest after fetching all from cache.