-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Open
Labels
blocked: firebase-sdkplatform: iosIssues / PRs which are specifically for iOS.Issues / PRs which are specifically for iOS.plugin: cloud_firestoretype: bugSomething isn't workingSomething isn't working
Description
Is there an existing issue for this?
- I have searched the existing issues.
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 = truedoc.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.2Additional 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.cachequeries correctly show the field — only default-source snapshot listeners are affected
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
blocked: firebase-sdkplatform: iosIssues / PRs which are specifically for iOS.Issues / PRs which are specifically for iOS.plugin: cloud_firestoretype: bugSomething isn't workingSomething isn't working