use of com.google.firebase.firestore.remote.TargetChange in project firebase-android-sdk by firebase.
the class SyncEngine method emitNewSnapsAndNotifyLocalStore.
/**
* Computes a new snapshot from the changes and calls the registered callback with the new
* snapshot.
*/
private void emitNewSnapsAndNotifyLocalStore(ImmutableSortedMap<DocumentKey, Document> changes, @Nullable RemoteEvent remoteEvent) {
List<ViewSnapshot> newSnapshots = new ArrayList<>();
List<LocalViewChanges> documentChangesInAllViews = new ArrayList<>();
for (Map.Entry<Query, QueryView> entry : queryViewsByQuery.entrySet()) {
QueryView queryView = entry.getValue();
View view = queryView.getView();
View.DocumentChanges viewDocChanges = view.computeDocChanges(changes);
if (viewDocChanges.needsRefill()) {
// The query has a limit and some docs were removed/updated, so we need to re-run the query
// against the local store to make sure we didn't lose any good docs that had been past the
// limit.
QueryResult queryResult = localStore.executeQuery(queryView.getQuery(), /* usePreviousResults= */
false);
viewDocChanges = view.computeDocChanges(queryResult.getDocuments(), viewDocChanges);
}
TargetChange targetChange = remoteEvent == null ? null : remoteEvent.getTargetChanges().get(queryView.getTargetId());
ViewChange viewChange = queryView.getView().applyChanges(viewDocChanges, targetChange);
updateTrackedLimboDocuments(viewChange.getLimboChanges(), queryView.getTargetId());
if (viewChange.getSnapshot() != null) {
newSnapshots.add(viewChange.getSnapshot());
LocalViewChanges docChanges = LocalViewChanges.fromViewSnapshot(queryView.getTargetId(), viewChange.getSnapshot());
documentChangesInAllViews.add(docChanges);
}
}
syncEngineListener.onViewSnapshots(newSnapshots);
localStore.notifyLocalViewChanges(documentChangesInAllViews);
}
use of com.google.firebase.firestore.remote.TargetChange in project firebase-android-sdk by firebase.
the class SyncEngine method initializeViewAndComputeSnapshot.
private ViewSnapshot initializeViewAndComputeSnapshot(Query query, int targetId) {
QueryResult queryResult = localStore.executeQuery(query, /* usePreviousResults= */
true);
SyncState currentTargetSyncState = SyncState.NONE;
TargetChange synthesizedCurrentChange = null;
// apply the sync state from those queries to the new query.
if (this.queriesByTarget.get(targetId) != null) {
Query mirrorQuery = this.queriesByTarget.get(targetId).get(0);
currentTargetSyncState = this.queryViewsByQuery.get(mirrorQuery).getView().getSyncState();
synthesizedCurrentChange = TargetChange.createSynthesizedTargetChangeForCurrentChange(currentTargetSyncState == SyncState.SYNCED);
}
// TODO(wuandy): Investigate if we can extract the logic of view change computation and
// update tracked limbo in one place, and have both emitNewSnapsAndNotifyLocalStore
// and here to call that.
View view = new View(query, queryResult.getRemoteKeys());
View.DocumentChanges viewDocChanges = view.computeDocChanges(queryResult.getDocuments());
ViewChange viewChange = view.applyChanges(viewDocChanges, synthesizedCurrentChange);
updateTrackedLimboDocuments(viewChange.getLimboChanges(), targetId);
QueryView queryView = new QueryView(query, targetId, view);
queryViewsByQuery.put(query, queryView);
if (!queriesByTarget.containsKey(targetId)) {
// Most likely there will only be one query mapping to a target, so construct the
// query list with capacity 1.
queriesByTarget.put(targetId, new ArrayList<>(1));
}
queriesByTarget.get(targetId).add(query);
return viewChange.getSnapshot();
}
use of com.google.firebase.firestore.remote.TargetChange in project firebase-android-sdk by firebase.
the class QueryListenerTest method testRaisesEventForEmptyCollectionsAfterSync.
@Test
public void testRaisesEventForEmptyCollectionsAfterSync() {
final List<ViewSnapshot> accum = new ArrayList<>();
Query query = Query.atPath(path("rooms"));
QueryListener listener = queryListener(query, accum);
View view = new View(query, DocumentKey.emptyKeySet());
ViewSnapshot snap1 = applyChanges(view);
TargetChange ackTarget = ackTarget();
ViewSnapshot snap2 = view.applyChanges(view.computeDocChanges(docUpdates()), ackTarget).getSnapshot();
listener.onViewSnapshot(snap1);
assertEquals(asList(), accum);
listener.onViewSnapshot(snap2);
assertEquals(asList(snap2), accum);
}
use of com.google.firebase.firestore.remote.TargetChange in project firebase-android-sdk by firebase.
the class ViewTest method testResumingQueryCreatesNoLimbos.
@Test
public void testResumingQueryCreatesNoLimbos() {
Query query = messageQuery();
MutableDocument doc1 = doc("rooms/eros/messages/0", 0, map());
MutableDocument doc2 = doc("rooms/eros/messages/1", 0, map());
// Unlike other cases, here the view is initialized with a set of previously synced documents
// which happens when listening to a previously listened-to query.
View view = new View(query, keySet(doc1.getKey(), doc2.getKey()));
TargetChange markCurrent = ackTarget();
View.DocumentChanges changes = view.computeDocChanges(docUpdates());
ViewChange change = view.applyChanges(changes, markCurrent);
assertEquals(emptyList(), change.getLimboChanges());
}
use of com.google.firebase.firestore.remote.TargetChange in project firebase-android-sdk by firebase.
the class TestUtil method targetChange.
public static TargetChange targetChange(ByteString resumeToken, boolean current, @Nullable Collection<MutableDocument> addedDocuments, @Nullable Collection<MutableDocument> modifiedDocuments, @Nullable Collection<? extends MutableDocument> removedDocuments) {
ImmutableSortedSet<DocumentKey> addedDocumentKeys = DocumentKey.emptyKeySet();
ImmutableSortedSet<DocumentKey> modifiedDocumentKeys = DocumentKey.emptyKeySet();
ImmutableSortedSet<DocumentKey> removedDocumentKeys = DocumentKey.emptyKeySet();
if (addedDocuments != null) {
for (MutableDocument document : addedDocuments) {
addedDocumentKeys = addedDocumentKeys.insert(document.getKey());
}
}
if (modifiedDocuments != null) {
for (MutableDocument document : modifiedDocuments) {
modifiedDocumentKeys = modifiedDocumentKeys.insert(document.getKey());
}
}
if (removedDocuments != null) {
for (MutableDocument document : removedDocuments) {
removedDocumentKeys = removedDocumentKeys.insert(document.getKey());
}
}
return new TargetChange(resumeToken, current, addedDocumentKeys, modifiedDocumentKeys, removedDocumentKeys);
}
Aggregations