Search in sources :

Example 1 with ViewSnapshot

use of com.google.firebase.firestore.core.ViewSnapshot in project firebase-android-sdk by firebase.

the class QuerySnapshotTest method testIncludeMetadataChanges.

@Test
public void testIncludeMetadataChanges() {
    MutableDocument doc1Old = doc("foo/bar", 1, wrapObject("a", "b")).setHasLocalMutations();
    MutableDocument doc1New = doc("foo/bar", 1, wrapObject("a", "b"));
    MutableDocument doc2Old = doc("foo/baz", 1, wrapObject("a", "b"));
    MutableDocument doc2New = doc("foo/baz", 1, wrapObject("a", "c"));
    DocumentSet oldDocuments = docSet(Document.KEY_COMPARATOR, doc1Old, doc2Old);
    DocumentSet newDocuments = docSet(Document.KEY_COMPARATOR, doc1New, doc2New);
    List<DocumentViewChange> documentChanges = Arrays.asList(DocumentViewChange.create(DocumentViewChange.Type.METADATA, doc1New), DocumentViewChange.create(DocumentViewChange.Type.MODIFIED, doc2New));
    FirebaseFirestore firestore = TestUtil.firestore();
    com.google.firebase.firestore.core.Query fooQuery = query("foo");
    ViewSnapshot viewSnapshot = new ViewSnapshot(fooQuery, newDocuments, oldDocuments, documentChanges, /*isFromCache=*/
    false, /*mutatedKeys=*/
    keySet(), /*didSyncStateChange=*/
    true, /* excludesMetadataChanges= */
    false);
    QuerySnapshot snapshot = new QuerySnapshot(new Query(fooQuery, firestore), viewSnapshot, firestore);
    QueryDocumentSnapshot doc1Snap = QueryDocumentSnapshot.fromDocument(firestore, doc1New, /*fromCache=*/
    false, /*hasPendingWrites=*/
    false);
    QueryDocumentSnapshot doc2Snap = QueryDocumentSnapshot.fromDocument(firestore, doc2New, /*fromCache=*/
    false, /*hasPendingWrites=*/
    false);
    assertEquals(1, snapshot.getDocumentChanges().size());
    List<DocumentChange> changesWithoutMetadata = Arrays.asList(new DocumentChange(doc2Snap, DocumentChange.Type.MODIFIED, /*oldIndex=*/
    1, /*newIndex=*/
    1));
    assertEquals(changesWithoutMetadata, snapshot.getDocumentChanges());
    List<DocumentChange> changesWithMetadata = Arrays.asList(new DocumentChange(doc1Snap, DocumentChange.Type.MODIFIED, /*oldIndex=*/
    0, /*newIndex=*/
    0), new DocumentChange(doc2Snap, DocumentChange.Type.MODIFIED, /*oldIndex=*/
    1, /*newIndex=*/
    1));
    assertEquals(changesWithMetadata, snapshot.getDocumentChanges(MetadataChanges.INCLUDE));
}
Also used : MutableDocument(com.google.firebase.firestore.model.MutableDocument) ViewSnapshot(com.google.firebase.firestore.core.ViewSnapshot) DocumentViewChange(com.google.firebase.firestore.core.DocumentViewChange) DocumentSet(com.google.firebase.firestore.model.DocumentSet) Test(org.junit.Test)

Example 2 with ViewSnapshot

use of com.google.firebase.firestore.core.ViewSnapshot in project firebase-android-sdk by firebase.

the class TestUtil method querySnapshot.

/**
 * A convenience method for creating a particular query snapshot for tests.
 *
 * @param path To be used in constructing the query.
 * @param oldDocs Provides the prior set of documents in the QuerySnapshot. Each entry maps to a
 *     document, with the key being the document id, and the value being the document contents.
 * @param docsToAdd Specifies data to be added into the query snapshot as of now. Each entry maps
 *     to a document, with the key being the document id, and the value being the document
 *     contents.
 * @param isFromCache Whether the query snapshot is cache result.
 * @return A query snapshot that consists of both sets of documents.
 */
public static QuerySnapshot querySnapshot(String path, Map<String, ObjectValue> oldDocs, Map<String, ObjectValue> docsToAdd, boolean hasPendingWrites, boolean isFromCache) {
    DocumentSet oldDocuments = docSet(Document.KEY_COMPARATOR);
    ImmutableSortedSet<DocumentKey> mutatedKeys = DocumentKey.emptyKeySet();
    for (Map.Entry<String, ObjectValue> pair : oldDocs.entrySet()) {
        String docKey = path + "/" + pair.getKey();
        MutableDocument doc = doc(docKey, 1L, pair.getValue());
        if (hasPendingWrites) {
            doc.setHasCommittedMutations();
            mutatedKeys = mutatedKeys.insert(key(docKey));
        }
        oldDocuments = oldDocuments.add(doc);
    }
    DocumentSet newDocuments = docSet(Document.KEY_COMPARATOR);
    List<DocumentViewChange> documentChanges = new ArrayList<>();
    for (Map.Entry<String, ObjectValue> pair : docsToAdd.entrySet()) {
        String docKey = path + "/" + pair.getKey();
        MutableDocument docToAdd = doc(docKey, 1L, pair.getValue());
        if (hasPendingWrites) {
            docToAdd.setHasCommittedMutations();
            mutatedKeys = mutatedKeys.insert(key(docKey));
        }
        newDocuments = newDocuments.add(docToAdd);
        documentChanges.add(DocumentViewChange.create(Type.ADDED, docToAdd));
    }
    ViewSnapshot viewSnapshot = new ViewSnapshot(com.google.firebase.firestore.testutil.TestUtil.query(path), newDocuments, oldDocuments, documentChanges, isFromCache, mutatedKeys, /* didSyncStateChange= */
    true, /* excludesMetadataChanges= */
    false);
    return new QuerySnapshot(query(path), viewSnapshot, FIRESTORE);
}
Also used : MutableDocument(com.google.firebase.firestore.model.MutableDocument) ArrayList(java.util.ArrayList) ViewSnapshot(com.google.firebase.firestore.core.ViewSnapshot) ObjectValue(com.google.firebase.firestore.model.ObjectValue) DocumentViewChange(com.google.firebase.firestore.core.DocumentViewChange) DocumentKey(com.google.firebase.firestore.model.DocumentKey) DocumentSet(com.google.firebase.firestore.model.DocumentSet) Map(java.util.Map)

Example 3 with ViewSnapshot

use of com.google.firebase.firestore.core.ViewSnapshot in project firebase-android-sdk by firebase.

the class DocumentChangeTest method validatePositions.

private static void validatePositions(com.google.firebase.firestore.core.Query query, Collection<MutableDocument> initialDocsList, Collection<MutableDocument> addedList, Collection<MutableDocument> modifiedList, Collection<MutableDocument> removedList) {
    ImmutableSortedMap<DocumentKey, Document> initialDocs = docUpdates(initialDocsList.toArray(new MutableDocument[] {}));
    ImmutableSortedMap<DocumentKey, Document> updates = emptyDocumentMap();
    for (MutableDocument doc : addedList) {
        updates = updates.insert(doc.getKey(), doc);
    }
    for (MutableDocument doc : modifiedList) {
        updates = updates.insert(doc.getKey(), doc);
    }
    for (MutableDocument doc : removedList) {
        updates = updates.insert(doc.getKey(), doc);
    }
    View view = new View(query, DocumentKey.emptyKeySet());
    View.DocumentChanges initialChanges = view.computeDocChanges(initialDocs);
    TargetChange initialTargetChange = ackTarget(initialDocsList.toArray(new MutableDocument[] {}));
    ViewSnapshot initialSnapshot = view.applyChanges(initialChanges, initialTargetChange).getSnapshot();
    View.DocumentChanges updateChanges = view.computeDocChanges(updates);
    TargetChange updateTargetChange = targetChange(ByteString.EMPTY, true, addedList, modifiedList, removedList);
    ViewSnapshot updatedSnapshot = view.applyChanges(updateChanges, updateTargetChange).getSnapshot();
    if (updatedSnapshot == null) {
        // Nothing changed, no positions to verify
        return;
    }
    List<Document> expected = new ArrayList<>(updatedSnapshot.getDocuments().toList());
    List<Document> actual = new ArrayList<>(initialSnapshot.getDocuments().toList());
    FirebaseFirestore firestore = mock(FirebaseFirestore.class);
    List<DocumentChange> changes = DocumentChange.changesFromSnapshot(firestore, MetadataChanges.EXCLUDE, updatedSnapshot);
    for (DocumentChange change : changes) {
        if (change.getType() != Type.ADDED) {
            actual.remove(change.getOldIndex());
        }
        if (change.getType() != Type.REMOVED) {
            actual.add(change.getNewIndex(), change.getDocument().getDocument());
        }
    }
    assertEquals(expected, actual);
}
Also used : MutableDocument(com.google.firebase.firestore.model.MutableDocument) ArrayList(java.util.ArrayList) Document(com.google.firebase.firestore.model.Document) MutableDocument(com.google.firebase.firestore.model.MutableDocument) View(com.google.firebase.firestore.core.View) ViewSnapshot(com.google.firebase.firestore.core.ViewSnapshot) TargetChange(com.google.firebase.firestore.remote.TargetChange) DocumentKey(com.google.firebase.firestore.model.DocumentKey)

Example 4 with ViewSnapshot

use of com.google.firebase.firestore.core.ViewSnapshot in project firebase-android-sdk by firebase.

the class DocumentReference method addSnapshotListenerInternal.

/**
 * Internal helper method to create add a snapshot listener.
 *
 * <p>Will be Activity scoped if the activity parameter is non-{@code null}.
 *
 * @param userExecutor The executor to use to call the listener.
 * @param options The options to use for this listen.
 * @param activity Optional activity this listener is scoped to.
 * @param userListener The user-supplied event listener that will be called with document
 *     snapshots.
 * @return A registration object that can be used to remove the listener.
 */
private ListenerRegistration addSnapshotListenerInternal(Executor userExecutor, ListenOptions options, @Nullable Activity activity, EventListener<DocumentSnapshot> userListener) {
    // Convert from ViewSnapshots to DocumentSnapshots.
    EventListener<ViewSnapshot> viewListener = (snapshot, error) -> {
        if (error != null) {
            userListener.onEvent(null, error);
            return;
        }
        Assert.hardAssert(snapshot != null, "Got event without value or error set");
        Assert.hardAssert(snapshot.getDocuments().size() <= 1, "Too many documents returned on a document query");
        Document document = snapshot.getDocuments().getDocument(key);
        DocumentSnapshot documentSnapshot;
        if (document != null) {
            boolean hasPendingWrites = snapshot.getMutatedKeys().contains(document.getKey());
            documentSnapshot = DocumentSnapshot.fromDocument(firestore, document, snapshot.isFromCache(), hasPendingWrites);
        } else {
            // We don't raise `hasPendingWrites` for deleted documents.
            documentSnapshot = DocumentSnapshot.fromNoDocument(firestore, key, snapshot.isFromCache());
        }
        userListener.onEvent(documentSnapshot, null);
    };
    // Call the viewListener on the userExecutor.
    AsyncEventListener<ViewSnapshot> asyncListener = new AsyncEventListener<>(userExecutor, viewListener);
    com.google.firebase.firestore.core.Query query = asQuery();
    QueryListener queryListener = firestore.getClient().listen(query, options, asyncListener);
    return ActivityScope.bind(activity, new ListenerRegistrationImpl(firestore.getClient(), queryListener, asyncListener));
}
Also used : ViewSnapshot(com.google.firebase.firestore.core.ViewSnapshot) AsyncEventListener(com.google.firebase.firestore.core.AsyncEventListener) NonNull(androidx.annotation.NonNull) Task(com.google.android.gms.tasks.Task) Collections.singletonList(java.util.Collections.singletonList) Code(com.google.firebase.firestore.FirebaseFirestoreException.Code) Map(java.util.Map) ParsedSetData(com.google.firebase.firestore.core.UserData.ParsedSetData) Util.voidErrorTransformer(com.google.firebase.firestore.util.Util.voidErrorTransformer) Assert(com.google.firebase.firestore.util.Assert) ListenerRegistrationImpl(com.google.firebase.firestore.core.ListenerRegistrationImpl) ParsedUpdateData(com.google.firebase.firestore.core.UserData.ParsedUpdateData) Precondition(com.google.firebase.firestore.model.mutation.Precondition) ActivityScope(com.google.firebase.firestore.core.ActivityScope) ListenOptions(com.google.firebase.firestore.core.EventManager.ListenOptions) Util(com.google.firebase.firestore.util.Util) Preconditions.checkNotNull(com.google.firebase.firestore.util.Preconditions.checkNotNull) Document(com.google.firebase.firestore.model.Document) Executor(java.util.concurrent.Executor) Executors(com.google.firebase.firestore.util.Executors) ResourcePath(com.google.firebase.firestore.model.ResourcePath) QueryListener(com.google.firebase.firestore.core.QueryListener) DeleteMutation(com.google.firebase.firestore.model.mutation.DeleteMutation) ExecutionException(java.util.concurrent.ExecutionException) Nullable(androidx.annotation.Nullable) Tasks(com.google.android.gms.tasks.Tasks) TaskCompletionSource(com.google.android.gms.tasks.TaskCompletionSource) Assert.fail(com.google.firebase.firestore.util.Assert.fail) Activity(android.app.Activity) Collections(java.util.Collections) DocumentKey(com.google.firebase.firestore.model.DocumentKey) Document(com.google.firebase.firestore.model.Document) ViewSnapshot(com.google.firebase.firestore.core.ViewSnapshot) ListenerRegistrationImpl(com.google.firebase.firestore.core.ListenerRegistrationImpl) QueryListener(com.google.firebase.firestore.core.QueryListener) AsyncEventListener(com.google.firebase.firestore.core.AsyncEventListener)

Example 5 with ViewSnapshot

use of com.google.firebase.firestore.core.ViewSnapshot in project firebase-android-sdk by firebase.

the class Query method addSnapshotListenerInternal.

/**
 * Internal helper method to create add a snapshot listener.
 *
 * <p>Will be Activity scoped if the activity parameter is non-{@code null}.
 *
 * @param executor The executor to use to call the listener.
 * @param options The options to use for this listen.
 * @param activity Optional activity this listener is scoped to.
 * @param userListener The user-supplied event listener that will be called with the snapshots.
 * @return A registration object that can be used to remove the listener.
 */
private ListenerRegistration addSnapshotListenerInternal(Executor executor, ListenOptions options, @Nullable Activity activity, EventListener<QuerySnapshot> userListener) {
    validateHasExplicitOrderByForLimitToLast();
    // Convert from ViewSnapshots to QuerySnapshots.
    EventListener<ViewSnapshot> viewListener = (@Nullable ViewSnapshot snapshot, @Nullable FirebaseFirestoreException error) -> {
        if (error != null) {
            userListener.onEvent(null, error);
            return;
        }
        hardAssert(snapshot != null, "Got event without value or error set");
        QuerySnapshot querySnapshot = new QuerySnapshot(this, snapshot, firestore);
        userListener.onEvent(querySnapshot, null);
    };
    // Call the viewListener on the userExecutor.
    AsyncEventListener<ViewSnapshot> asyncListener = new AsyncEventListener<>(executor, viewListener);
    QueryListener queryListener = firestore.getClient().listen(query, options, asyncListener);
    return ActivityScope.bind(activity, new ListenerRegistrationImpl(firestore.getClient(), queryListener, asyncListener));
}
Also used : ViewSnapshot(com.google.firebase.firestore.core.ViewSnapshot) ListenerRegistrationImpl(com.google.firebase.firestore.core.ListenerRegistrationImpl) QueryListener(com.google.firebase.firestore.core.QueryListener) AsyncEventListener(com.google.firebase.firestore.core.AsyncEventListener)

Aggregations

ViewSnapshot (com.google.firebase.firestore.core.ViewSnapshot)5 DocumentKey (com.google.firebase.firestore.model.DocumentKey)3 MutableDocument (com.google.firebase.firestore.model.MutableDocument)3 AsyncEventListener (com.google.firebase.firestore.core.AsyncEventListener)2 DocumentViewChange (com.google.firebase.firestore.core.DocumentViewChange)2 ListenerRegistrationImpl (com.google.firebase.firestore.core.ListenerRegistrationImpl)2 QueryListener (com.google.firebase.firestore.core.QueryListener)2 Document (com.google.firebase.firestore.model.Document)2 DocumentSet (com.google.firebase.firestore.model.DocumentSet)2 ArrayList (java.util.ArrayList)2 Map (java.util.Map)2 Activity (android.app.Activity)1 NonNull (androidx.annotation.NonNull)1 Nullable (androidx.annotation.Nullable)1 Task (com.google.android.gms.tasks.Task)1 TaskCompletionSource (com.google.android.gms.tasks.TaskCompletionSource)1 Tasks (com.google.android.gms.tasks.Tasks)1 Code (com.google.firebase.firestore.FirebaseFirestoreException.Code)1 ActivityScope (com.google.firebase.firestore.core.ActivityScope)1 ListenOptions (com.google.firebase.firestore.core.EventManager.ListenOptions)1