diff --git a/firebase-firestore/src/main/java/com/google/firebase/firestore/local/LocalDocumentsView.java b/firebase-firestore/src/main/java/com/google/firebase/firestore/local/LocalDocumentsView.java index 1ffab1aa3f9..9642f1bbdc6 100644 --- a/firebase-firestore/src/main/java/com/google/firebase/firestore/local/LocalDocumentsView.java +++ b/firebase-firestore/src/main/java/com/google/firebase/firestore/local/LocalDocumentsView.java @@ -91,7 +91,7 @@ Document getDocument(DocumentKey key) { Overlay overlay = documentOverlayCache.getOverlay(key); MutableDocument document = getBaseDocument(key, overlay); if (overlay != null) { - overlay.getMutation().applyToLocalView(document, null, Timestamp.now()); + overlay.getMutation().applyToLocalView(document, FieldMask.EMPTY, Timestamp.now()); } return document; } @@ -171,7 +171,9 @@ private Map computeViews( recalculateDocuments.put(doc.getKey(), doc); } else if (overlay != null) { mutatedFields.put(doc.getKey(), overlay.getMutation().getFieldMask()); - overlay.getMutation().applyToLocalView(doc, null, Timestamp.now()); + overlay + .getMutation() + .applyToLocalView(doc, overlay.getMutation().getFieldMask(), Timestamp.now()); } } @@ -375,7 +377,9 @@ private ImmutableSortedMap getDocumentsMatchingCollection for (Map.Entry docEntry : remoteDocuments.entrySet()) { Overlay overlay = overlays.get(docEntry.getKey()); if (overlay != null) { - overlay.getMutation().applyToLocalView(docEntry.getValue(), null, Timestamp.now()); + overlay + .getMutation() + .applyToLocalView(docEntry.getValue(), FieldMask.EMPTY, Timestamp.now()); } // Finally, insert the documents that still match the query if (query.matches(docEntry.getValue())) { diff --git a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/LocalStoreTestCase.java b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/LocalStoreTestCase.java index 101ff47877a..6c138084006 100644 --- a/firebase-firestore/src/test/java/com/google/firebase/firestore/local/LocalStoreTestCase.java +++ b/firebase-firestore/src/test/java/com/google/firebase/firestore/local/LocalStoreTestCase.java @@ -1337,16 +1337,17 @@ public void testHoldsBackTransforms() { emptyList())); assertChanged(doc("foo/bar", 1, map("sum", 0, "array_union", new ArrayList<>()))); - writeMutations( - asList( - patchMutation("foo/bar", map("sum", FieldValue.increment(1))), - patchMutation("foo/bar", map("array_union", FieldValue.arrayUnion("foo"))))); + writeMutation(patchMutation("foo/bar", map("sum", FieldValue.increment(1)))); + assertChanged( + doc("foo/bar", 1, map("sum", 1, "array_union", new ArrayList<>())).setHasLocalMutations()); + + writeMutation(patchMutation("foo/bar", map("array_union", FieldValue.arrayUnion("foo")))); assertChanged( doc("foo/bar", 1, map("sum", 1, "array_union", Collections.singletonList("foo"))) .setHasLocalMutations()); - // The sum transform is not idempotent and the backend's updated value is ignored. The - // ArrayUnion transform is recomputed and includes the backend value. + // The sum transform and array union transform make the SDK ignore the + // backend's updated value. applyRemoteEvent( addedRemoteEvent( doc("foo/bar", 2, map("sum", 1337, "array_union", Collections.singletonList("bar"))), @@ -1355,10 +1356,18 @@ public void testHoldsBackTransforms() { assertChanged( doc("foo/bar", 2, map("sum", 1, "array_union", asList("foo"))).setHasLocalMutations()); - acknowledgeMutationWithTransformResults(3, 1338, asList("bar", "foo")); + // With a field transform acknowledgement, the overlay is recalculated with + // remaining local mutations. + acknowledgeMutationWithTransformResults(3, 1338); assertChanged( doc("foo/bar", 3, map("sum", 1338, "array_union", asList("bar", "foo"))) .setReadTime(new SnapshotVersion(new Timestamp(0, 3000))) + .setHasLocalMutations()); + + acknowledgeMutationWithTransformResults(4, asList("bar", "foo")); + assertChanged( + doc("foo/bar", 4, map("sum", 1338, "array_union", asList("bar", "foo"))) + .setReadTime(new SnapshotVersion(new Timestamp(0, 4000))) .setHasCommittedMutations()); }