serverSnapshots method

Stream<DocumentSnapshot<T>> serverSnapshots()

Implementation

Stream<DocumentSnapshot<T>> serverSnapshots() {
  // According to the docs: https://firebase.google.com/docs/firestore/query-data/listen#events-metadata-changes
  // The sequence of events when performing client-side Firestore writes *with* metadata changes is as follows:
  // 1. An immediate event fired with the new data. The document has not yet been written to the backend so the "pending writes" flag is true and isFromCache is false
  // because this is an event destined to reflect the state of the server (a little unintuitive).
  // ```
  // SnapshotMetadata(isFromCache: false, hasPendingWrites: true)
  // ```
  // 2. The backend then notifies the client of the successful write when it's done. There is no change to the document data, but there is a metadata change because the "pending writes" flag is now false.
  // to indicate that the document was successfully written.
  // ```
  // SnapshotMetadata(isFromCache: false, hasPendingWrites: false)
  // ```
  //
  // Whereas the sequence when perform client-side Firestore writes *without* metadata changes is only the first event.
  //
  // To guarantee that a server snapshot as a result of a client-side write has been persisted to the server, the behavior you would want for a serverOnly policy
  // that uses serverSnapshots would therefore be to filter the snapshots with metadata change events once hasPendingWrites has become false:
  //
  // ```
  // snapshots(includeMetadataChanges: true).where((snap) => !snap.metadata.isFromCache && !snap.metadata.hasPendingWrites);
  // ```
  //
  // The downside to this approach is that it delays receiving the update for the write event and also leaves you vulnerable to inconsistencies
  // where a cache-only write (into Nimbostratus' in-memory cache) that immediately follows a server-bound write would be blown away by the delayed server response.
  // To mitigate these issues, at this time metadata changes are *not* included and client side writes will immediately emit server changes before the server
  // has indicated the write was successful.
  //
  // There is an argument to be made that this is incorrect but it is also the default behavior (includeMetadataChanges defaults to false) and it can be re-visited
  // in the future if related issues arise.
  return snapshots(includeMetadataChanges: false).cast<DocumentSnapshot<T>>();
}