use of com.google.firebase.firestore.local.TargetData in project firebase-android-sdk by firebase.
the class RemoteEventTest method testWillHandleTargetAddAndRemovalInSameBatch.
@Test
public void testWillHandleTargetAddAndRemovalInSameBatch() {
Map<Integer, TargetData> targetMap = activeQueries(1, 2);
MutableDocument doc1a = doc("docs/1", 1, map("value", 1));
MutableDocument doc1b = doc("docs/1", 1, map("value", 2));
WatchChange change1 = new DocumentChange(asList(1), asList(2), doc1a.getKey(), doc1a);
WatchChange change2 = new DocumentChange(asList(2), asList(1), doc1b.getKey(), doc1b);
RemoteEvent event = createRemoteEvent(3, targetMap, noOutstandingResponses, keySet(doc1a.getKey()), change1, change2);
assertEquals(version(3), event.getSnapshotVersion());
assertEquals(1, event.getDocumentUpdates().size());
assertEquals(doc1b, event.getDocumentUpdates().get(doc1b.getKey()));
assertEquals(2, event.getTargetChanges().size());
TargetChange mapping1 = targetChange(resumeToken, false, null, null, asList(doc1b));
assertEquals(mapping1, event.getTargetChanges().get(1));
TargetChange mapping2 = targetChange(resumeToken, false, null, asList(doc1b), null);
assertEquals(mapping2, event.getTargetChanges().get(2));
}
use of com.google.firebase.firestore.local.TargetData in project firebase-android-sdk by firebase.
the class RemoteSerializerTest method testEncodesResumeTokens.
@Test
public void testEncodesResumeTokens() {
Query q = Query.atPath(ResourcePath.fromString("docs"));
TargetData targetData = new TargetData(q.toTarget(), 1, 2, QueryPurpose.LISTEN).withResumeToken(TestUtil.resumeToken(1000), SnapshotVersion.NONE);
Target actual = serializer.encodeTarget(targetData);
StructuredQuery.Builder structuredQueryBuilder = StructuredQuery.newBuilder().addFrom(CollectionSelector.newBuilder().setCollectionId("docs")).addOrderBy(defaultKeyOrder());
QueryTarget.Builder queryBuilder = QueryTarget.newBuilder().setParent("projects/p/databases/d/documents").setStructuredQuery(structuredQueryBuilder);
Target expected = Target.newBuilder().setQuery(queryBuilder).setTargetId(1).setResumeToken(TestUtil.resumeToken(1000)).build();
assertEquals(expected, actual);
assertEquals(serializer.decodeQueryTarget(serializer.encodeQueryTarget(q.toTarget())), q.toTarget());
}
use of com.google.firebase.firestore.local.TargetData in project firebase-android-sdk by firebase.
the class RemoteSerializerTest method testEncodesListenRequestLabels.
@Test
public void testEncodesListenRequestLabels() {
Query query = query("collection/key");
TargetData targetData = new TargetData(query.toTarget(), 2, 3, QueryPurpose.LISTEN);
Map<String, String> result = serializer.encodeListenRequestLabels(targetData);
assertNull(result);
targetData = new TargetData(query.toTarget(), 2, 3, QueryPurpose.LIMBO_RESOLUTION);
result = serializer.encodeListenRequestLabels(targetData);
assertEquals(map("goog-listen-tags", "limbo-document"), result);
targetData = new TargetData(query.toTarget(), 2, 3, QueryPurpose.EXISTENCE_FILTER_MISMATCH);
result = serializer.encodeListenRequestLabels(targetData);
assertEquals(map("goog-listen-tags", "existence-filter-mismatch"), result);
}
use of com.google.firebase.firestore.local.TargetData in project firebase-android-sdk by firebase.
the class WatchChangeAggregator method handleExistenceFilter.
/**
* Handles existence filters and synthesizes deletes for filter mismatches. Targets that are
* invalidated by filter mismatches are added to `pendingTargetResets`.
*/
public void handleExistenceFilter(ExistenceFilterWatchChange watchChange) {
int targetId = watchChange.getTargetId();
int expectedCount = watchChange.getExistenceFilter().getCount();
TargetData targetData = queryDataForActiveTarget(targetId);
if (targetData != null) {
Target target = targetData.getTarget();
if (target.isDocumentQuery()) {
if (expectedCount == 0) {
// The existence filter told us the document does not exist. We deduce that this document
// does not exist and apply a deleted document to our updates. Without applying this
// deleted document there might be another query that will raise this document as part of
// a snapshot until it is resolved, essentially exposing inconsistency between queries.
DocumentKey key = DocumentKey.fromPath(target.getPath());
MutableDocument result = MutableDocument.newNoDocument(key, SnapshotVersion.NONE);
removeDocumentFromTarget(targetId, key, result);
} else {
hardAssert(expectedCount == 1, "Single document existence filter with count: %d", expectedCount);
}
} else {
long currentSize = getCurrentDocumentCountForTarget(targetId);
if (currentSize != expectedCount) {
// Existence filter mismatch: We reset the mapping and raise a new snapshot with
// `isFromCache:true`.
resetTarget(targetId);
pendingTargetResets.add(targetId);
}
}
}
}
use of com.google.firebase.firestore.local.TargetData in project firebase-android-sdk by firebase.
the class TestUtil method existenceFilterEvent.
public static RemoteEvent existenceFilterEvent(int targetId, ImmutableSortedSet<DocumentKey> syncedKeys, int remoteCount, int version) {
TargetData targetData = TestUtil.targetData(targetId, QueryPurpose.LISTEN, "foo");
TestTargetMetadataProvider testTargetMetadataProvider = new TestTargetMetadataProvider();
testTargetMetadataProvider.setSyncedKeys(targetData, syncedKeys);
ExistenceFilter existenceFilter = new ExistenceFilter(remoteCount);
WatchChangeAggregator aggregator = new WatchChangeAggregator(testTargetMetadataProvider);
WatchChange.ExistenceFilterWatchChange existenceFilterWatchChange = new WatchChange.ExistenceFilterWatchChange(targetId, existenceFilter);
aggregator.handleExistenceFilter(existenceFilterWatchChange);
return aggregator.createRemoteEvent(version(version));
}
Aggregations