Skip to content

Commit d0b9ccc

Browse files
Idempotency: Address TODOs, add Changelog (#2270)
1 parent 83ccb76 commit d0b9ccc

File tree

3 files changed

+54
-65
lines changed

3 files changed

+54
-65
lines changed

packages/firestore/CHANGELOG.md

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
# Unreleased
2+
- [changed] Fixed a crash on iOS 13 that occurred when persistence was enabled
3+
in a background tab (#2232).
4+
5+
# 1.6.0
26
- [fixed] Fixed a regression that caused queries with nested field filters to
37
crash the client if the field was not present in the local copy of the
48
document.
5-
9+
- [feature] Added a `Firestore.onSnapshotsInSync()` method that notifies you
10+
when all your snapshot listeners are in sync with each other.
11+
612
# 1.5.0
713
- [feature] Added a `Firestore.waitForPendingWrites()` method that
814
allows users to wait until all pending writes are acknowledged by the
@@ -15,8 +21,6 @@
1521
small subset of the documents in a collection.
1622
- [fixed] Fixed a race condition between authenticating and initializing
1723
Firestore that could result in initial writes to the database being dropped.
18-
- [feature] Added a `Firestore.onSnapshotsInSync()` method that notifies you
19-
when all your snapshot listeners are in sync with each other.
2024

2125
# 1.4.10
2226
- [changed] Transactions now perform exponential backoff before retrying.
@@ -35,7 +39,6 @@
3539
match the query (https://github.com/firebase/firebase-android-sdk/issues/155).
3640

3741
# 1.4.4
38-
>>>>>>> master
3942
- [fixed] Fixed an internal assertion that was triggered when an update
4043
with a `FieldValue.serverTimestamp()` and an update with a
4144
`FieldValue.increment()` were pending for the same document.

packages/firestore/src/local/simple_db.ts

-11
Original file line numberDiff line numberDiff line change
@@ -274,17 +274,6 @@ export class SimpleDb {
274274
);
275275
try {
276276
const transactionFnResult = transactionFn(transaction)
277-
// TODO(schmidt-sebastian): Remove this code/comment or find a way to
278-
// make this a test-only setting.
279-
// Horrible hack to verify that idempotent functions can be run more
280-
// than once.
281-
.next(result => {
282-
if (idempotent && attemptNumber === 1) {
283-
class DOMException {}
284-
throw new DOMException();
285-
}
286-
return result;
287-
})
288277
.catch(error => {
289278
// Abort the transaction if there was an error.
290279
transaction.abort(error);

packages/firestore/test/unit/local/local_store.test.ts

+47-50
Original file line numberDiff line numberDiff line change
@@ -1076,10 +1076,7 @@ function genericLocalStoreTests(
10761076
]);
10771077
});
10781078

1079-
// TODO(schmidt-sebastian): This test makes idempotency testing harder.
1080-
// Comment back in when done with the idempotent migration.
1081-
// eslint-disable-next-line no-restricted-properties
1082-
it.skip('reads all documents for initial collection queries', () => {
1079+
it('reads all documents for initial collection queries', () => {
10831080
const firstQuery = Query.atPath(path('foo'));
10841081
const secondQuery = Query.atPath(path('foo')).addFilter(
10851082
filter('matches', '==', true)
@@ -1483,55 +1480,55 @@ function genericLocalStoreTests(
14831480
);
14841481
});
14851482

1486-
// TODO(schmidt-sebastian): This test makes idempotency testing harder.
1487-
// Comment back in when done with the idempotent migration.
1488-
// (queryEngine instanceof IndexFreeQueryEngine && !gcIsEager ? it : it.skip)(
14891483
// eslint-disable-next-line no-restricted-properties
1490-
it.skip('uses target mapping to execute queries', () => {
1491-
// This test verifies that once a target mapping has been written, only
1492-
// documents that match the query are read from the RemoteDocumentCache.
1484+
(queryEngine instanceof IndexFreeQueryEngine && !gcIsEager ? it : it.skip)(
1485+
'uses target mapping to execute queries',
1486+
() => {
1487+
// This test verifies that once a target mapping has been written, only
1488+
// documents that match the query are read from the RemoteDocumentCache.
14931489

1494-
const query = Query.atPath(path('foo')).addFilter(
1495-
filter('matches', '==', true)
1496-
);
1497-
return (
1498-
expectLocalStore()
1499-
.afterAllocatingQuery(query)
1500-
.toReturnTargetId(2)
1501-
.after(setMutation('foo/a', { matches: true }))
1502-
.after(setMutation('foo/b', { matches: true }))
1503-
.after(setMutation('foo/ignored', { matches: false }))
1504-
.afterAcknowledgingMutation({ documentVersion: 10 })
1505-
.afterAcknowledgingMutation({ documentVersion: 10 })
1506-
.afterAcknowledgingMutation({ documentVersion: 10 })
1507-
.afterExecutingQuery(query)
1508-
// Execute the query, but note that we read all existing documents
1509-
// from the RemoteDocumentCache since we do not yet have target
1510-
// mapping.
1511-
.toHaveRead({ documentsByQuery: 2 })
1512-
.after(
1513-
docAddedRemoteEvent(
1514-
[
1515-
doc('foo/a', 10, { matches: true }),
1516-
doc('foo/b', 10, { matches: true })
1517-
],
1518-
[2],
1519-
[]
1490+
const query = Query.atPath(path('foo')).addFilter(
1491+
filter('matches', '==', true)
1492+
);
1493+
return (
1494+
expectLocalStore()
1495+
.afterAllocatingQuery(query)
1496+
.toReturnTargetId(2)
1497+
.after(setMutation('foo/a', { matches: true }))
1498+
.after(setMutation('foo/b', { matches: true }))
1499+
.after(setMutation('foo/ignored', { matches: false }))
1500+
.afterAcknowledgingMutation({ documentVersion: 10 })
1501+
.afterAcknowledgingMutation({ documentVersion: 10 })
1502+
.afterAcknowledgingMutation({ documentVersion: 10 })
1503+
.afterExecutingQuery(query)
1504+
// Execute the query, but note that we read all existing documents
1505+
// from the RemoteDocumentCache since we do not yet have target
1506+
// mapping.
1507+
.toHaveRead({ documentsByQuery: 2 })
1508+
.after(
1509+
docAddedRemoteEvent(
1510+
[
1511+
doc('foo/a', 10, { matches: true }),
1512+
doc('foo/b', 10, { matches: true })
1513+
],
1514+
[2],
1515+
[]
1516+
)
15201517
)
1521-
)
1522-
.after(
1523-
noChangeEvent(/* targetId= */ 2, /* snapshotVersion= */ 10, 'foo')
1524-
)
1525-
.after(localViewChanges(2, /* fromCache= */ false, {}))
1526-
.afterExecutingQuery(query)
1527-
.toHaveRead({ documentsByKey: 2, documentsByQuery: 0 })
1528-
.toReturnChanged(
1529-
doc('foo/a', 10, { matches: true }),
1530-
doc('foo/b', 10, { matches: true })
1531-
)
1532-
.finish()
1533-
);
1534-
});
1518+
.after(
1519+
noChangeEvent(/* targetId= */ 2, /* snapshotVersion= */ 10, 'foo')
1520+
)
1521+
.after(localViewChanges(2, /* fromCache= */ false, {}))
1522+
.afterExecutingQuery(query)
1523+
.toHaveRead({ documentsByKey: 2, documentsByQuery: 0 })
1524+
.toReturnChanged(
1525+
doc('foo/a', 10, { matches: true }),
1526+
doc('foo/b', 10, { matches: true })
1527+
)
1528+
.finish()
1529+
);
1530+
}
1531+
);
15351532

15361533
it('last limbo free snapshot is advanced during view processing', async () => {
15371534
// This test verifies that the `lastLimboFreeSnapshot` version for QueryData

0 commit comments

Comments
 (0)