Skip to content

Commit e532e95

Browse files
committed
fix: don't rely on excluding fromCache from onFirstData triggers
1 parent ebe60ee commit e532e95

File tree

2 files changed

+44
-13
lines changed

2 files changed

+44
-13
lines changed

packages/plugin-firestore/src/actions/stream.ts

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,13 @@ export function streamActionFactory(
4343
const documentPath = getFirestoreDocPath(collectionPath, docId, pluginModuleConfig, firestorePluginOptions) // prettier-ignore
4444
closeStream = onSnapshot(
4545
doc(db, documentPath),
46-
{ includeMetadataChanges: true },
4746
(docSnapshot: DocumentSnapshot<{ [key: string]: unknown }>) => {
4847
// even if `docSnapshot.metadata.hasPendingWrites`
4948
// we should always execute `added/modified`
5049
// because `core` handles overlapping calls for us
5150

5251
// Call onFirstData on first snapshot (whether doc exists or not)
53-
if (
54-
!firstDataReceived &&
55-
onFirstData &&
56-
!docSnapshot.metadata.fromCache &&
57-
!docSnapshot.metadata.hasPendingWrites
58-
) {
52+
if (!firstDataReceived && onFirstData) {
5953
firstDataReceived = true
6054
setTimeout(() => onFirstData({ empty: !docSnapshot.exists() }), 0)
6155
}
@@ -82,12 +76,7 @@ export function streamActionFactory(
8276
// because `core` handles overlapping calls for us
8377

8478
// Call onFirstData on first snapshot (whether collection has docs or not)
85-
if (
86-
!firstDataReceived &&
87-
onFirstData &&
88-
!querySnapshot.metadata.fromCache &&
89-
!querySnapshot.metadata.hasPendingWrites
90-
) {
79+
if (!firstDataReceived && onFirstData) {
9180
firstDataReceived = true
9281
setTimeout(() => onFirstData({ empty: querySnapshot.empty }), 0)
9382
}

packages/plugin-firestore/test/external/stream.test.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,48 @@ import { createMagnetarInstance } from '../helpers/createMagnetarInstance.js'
2222
assert.deepEqual(pokedexModule.data.size, 151)
2323
})
2424
}
25+
{
26+
const testName = 'stream with onFirstData (empty collection), close and stream again'
27+
test(testName, async () => {
28+
const { magnetar } = await createMagnetarInstance('read')
29+
30+
const emptyReadable = magnetar.collection('emptyReopen', {
31+
configPerStore: {
32+
remote: { firestorePath: 'magnetarTests/read/emptyReopen' },
33+
},
34+
})
35+
36+
const onFirstDataPayloads: { empty?: boolean }[] = []
37+
38+
// First stream
39+
emptyReadable
40+
.stream({ onFirstData: (payload) => onFirstDataPayloads.push(payload) })
41+
.catch((e: any) => assert.fail(e.message))
42+
43+
// Wait for initial snapshot
44+
await waitMs(500)
45+
46+
// Close all streams and wait a tick
47+
emptyReadable.closeAllStreams()
48+
await waitMs(10)
49+
50+
// Second stream
51+
emptyReadable
52+
.stream({ onFirstData: (payload) => onFirstDataPayloads.push(payload) })
53+
.catch((e: any) => assert.fail(e.message))
54+
55+
// Wait for second snapshot
56+
await waitMs(500)
57+
58+
// Expect onFirstData twice, both indicating empty collection
59+
assert.deepEqual(onFirstDataPayloads.length, 2)
60+
assert.deepEqual(onFirstDataPayloads[0], { empty: true })
61+
assert.deepEqual(onFirstDataPayloads[1], { empty: true })
62+
63+
// Cleanup
64+
emptyReadable.closeAllStreams()
65+
})
66+
}
2567
{
2668
const testName = 'stream (empty collection with read access)'
2769
test(testName, async () => {

0 commit comments

Comments
 (0)