Is there an existing issue for this?
Which plugins are affected?
Cloud Firestore
Which platforms are affected?
iOS
Description
When a document is created with docRef.set() and then docRef.update() is called on the same document before the set() is confirmed by the server, snapshot listeners drop a field from the optimistic state reconstruction.
Expected: all fields from the original set() should be present in the snapshot, merged with any pending update() mutations.
Actual: a plain string field is completely absent from the snapshot data — not even present in map.keys — even though:
- The field was confirmed present in the data passed to
set() (logged immediately before the call)
- A direct
doc.get(GetOptions(source: Source.server)) confirms the server has the field
- No
update() call ever touches or deletes that field
- Other plain fields from the same
set() call are preserved correctly
Diagnostic metadata on the broken snapshot:
doc.metadata.hasPendingWrites = true
doc.metadata.isFromCache = false
Reproducing the issue
final docRef = FirebaseFirestore.instance.collection('items').doc();
// 1. Create document with set(), do not await
unawaited(docRef.set({
'ownerId': 'user_123',
'title': 'Test item',
'createdAt': FieldValue.serverTimestamp(),
'status': 0,
}));
// 2. Call update() before the server confirms the set()
await Future.delayed(Duration(milliseconds: 100));
await docRef.update({
'retryCount': 1,
'errorMessage': FieldValue.delete(),
});
// 3. A default-source snapshot listener on a query covering this document
// returns the doc with 'ownerId' missing from the data map.
FirebaseFirestore.instance
.collection('items')
.orderBy('createdAt', descending: true)
.snapshots()
.listen((snapshot) {
for (final doc in snapshot.docs) {
final data = doc.data();
// 'ownerId' is missing from data.keys entirely
print('ownerId: ${data['ownerId']}'); // null
print('title: ${data['title']}'); // 'Test item' ✓
print('status: ${data['status']}'); // 0 ✓
// Direct server fetch confirms the field exists
doc.reference.get(GetOptions(source: Source.server)).then((serverDoc) {
print('server ownerId: ${serverDoc.data()?['ownerId']}'); // 'user_123' ✓
});
}
});
Firebase Core version
4.4.0
Flutter Version
3.38.9
Relevant Log Output
# set() data includes ownerId
[DIAG] ownerId=user_123, data={ownerId: user_123, title: Test item, createdAt: FieldValue(...), status: 0}
# Snapshot listener: ownerId not in keys
[DIAG] ownerId missing, hasPendingWrites=true, isFromCache=false, keys=[title, retryCount, createdAt, status]
# Direct server fetch: ownerId present
[DIAG] server doc: exists=true, ownerId=user_123, keys=[ownerId, title, retryCount, createdAt, status]
Flutter dependencies
Expand Flutter dependencies snippet
Dart SDK 3.10.8
Flutter SDK 3.38.9
- cloud_firestore 6.1.2
- firebase_core 4.4.0
- _flutterfire_internals 1.3.66
- cloud_firestore_platform_interface 7.0.6
- cloud_firestore_web 5.1.2
Additional context and comments
The server data is correct, so the issue is purely in the client-side optimistic state reconstruction. Subsequent snapshots (once all pending writes are confirmed) include the field correctly.
- Firestore offline persistence is enabled
- Tested on iOS physical device
ListenSource.cache queries correctly show the field — only default-source snapshot listeners are affected
Is there an existing issue for this?
Which plugins are affected?
Cloud Firestore
Which platforms are affected?
iOS
Description
When a document is created with
docRef.set()and thendocRef.update()is called on the same document before theset()is confirmed by the server, snapshot listeners drop a field from the optimistic state reconstruction.Expected: all fields from the original
set()should be present in the snapshot, merged with any pendingupdate()mutations.Actual: a plain string field is completely absent from the snapshot data — not even present in
map.keys— even though:set()(logged immediately before the call)doc.get(GetOptions(source: Source.server))confirms the server has the fieldupdate()call ever touches or deletes that fieldset()call are preserved correctlyDiagnostic metadata on the broken snapshot:
doc.metadata.hasPendingWrites = truedoc.metadata.isFromCache = falseReproducing the issue
Firebase Core version
4.4.0
Flutter Version
3.38.9
Relevant Log Output
Flutter dependencies
Expand
Flutter dependenciessnippetAdditional context and comments
The server data is correct, so the issue is purely in the client-side optimistic state reconstruction. Subsequent snapshots (once all pending writes are confirmed) include the field correctly.
ListenSource.cachequeries correctly show the field — only default-source snapshot listeners are affected