Search in sources :

Example 6 with ListenOptions

use of com.google.firebase.firestore.core.EventManager.ListenOptions 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 7 with ListenOptions

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

the class DocumentReference method internalOptions.

/**
 * Converts the public API MetadataChanges object to the internal options object.
 */
private static ListenOptions internalOptions(MetadataChanges metadataChanges) {
    ListenOptions internalOptions = new ListenOptions();
    internalOptions.includeDocumentMetadataChanges = (metadataChanges == MetadataChanges.INCLUDE);
    internalOptions.includeQueryMetadataChanges = (metadataChanges == MetadataChanges.INCLUDE);
    internalOptions.waitForSyncWhenOnline = false;
    return internalOptions;
}
Also used : ListenOptions(com.google.firebase.firestore.core.EventManager.ListenOptions)

Example 8 with ListenOptions

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

the class DocumentReference method getViaSnapshotListener.

@NonNull
private Task<DocumentSnapshot> getViaSnapshotListener(Source source) {
    final TaskCompletionSource<DocumentSnapshot> res = new TaskCompletionSource<>();
    final TaskCompletionSource<ListenerRegistration> registration = new TaskCompletionSource<>();
    ListenOptions options = new ListenOptions();
    options.includeDocumentMetadataChanges = true;
    options.includeQueryMetadataChanges = true;
    options.waitForSyncWhenOnline = true;
    ListenerRegistration listenerRegistration = addSnapshotListenerInternal(// No need to schedule, we just set the task result directly
    Executors.DIRECT_EXECUTOR, options, null, (snapshot, error) -> {
        if (error != null) {
            res.setException(error);
            return;
        }
        try {
            ListenerRegistration actualRegistration = Tasks.await(registration.getTask());
            // Remove query first before passing event to user to avoid user actions affecting
            // the now stale query.
            actualRegistration.remove();
            if (!snapshot.exists() && snapshot.getMetadata().isFromCache()) {
                // TODO: Reconsider how to raise missing documents when offline.
                // If we're online and the document doesn't exist then we set the result
                // of the Task with a document with document.exists set to false. If we're
                // offline however, we set the Exception on the Task. Two options:
                // 
                // 1)  Cache the negative response from the server so we can deliver that
                // even when you're offline.
                // 2)  Actually set the Exception of the Task if the document doesn't
                // exist when you are offline.
                res.setException(new FirebaseFirestoreException("Failed to get document because the client is offline.", Code.UNAVAILABLE));
            } else if (snapshot.exists() && snapshot.getMetadata().isFromCache() && source == Source.SERVER) {
                res.setException(new FirebaseFirestoreException("Failed to get document from server. (However, this document does exist " + "in the local cache. Run again without setting source to SERVER to " + "retrieve the cached document.)", Code.UNAVAILABLE));
            } else {
                res.setResult(snapshot);
            }
        } catch (ExecutionException e) {
            throw fail(e, "Failed to register a listener for a single document");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw fail(e, "Failed to register a listener for a single document");
        }
    });
    registration.setResult(listenerRegistration);
    return res.getTask();
}
Also used : TaskCompletionSource(com.google.android.gms.tasks.TaskCompletionSource) ListenOptions(com.google.firebase.firestore.core.EventManager.ListenOptions) ExecutionException(java.util.concurrent.ExecutionException) NonNull(androidx.annotation.NonNull)

Example 9 with ListenOptions

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

the class Query method getViaSnapshotListener.

private Task<QuerySnapshot> getViaSnapshotListener(Source source) {
    final TaskCompletionSource<QuerySnapshot> res = new TaskCompletionSource<>();
    final TaskCompletionSource<ListenerRegistration> registration = new TaskCompletionSource<>();
    ListenOptions options = new ListenOptions();
    options.includeDocumentMetadataChanges = true;
    options.includeQueryMetadataChanges = true;
    options.waitForSyncWhenOnline = true;
    ListenerRegistration listenerRegistration = addSnapshotListenerInternal(// No need to schedule, we just set the task result directly
    Executors.DIRECT_EXECUTOR, options, null, (snapshot, error) -> {
        if (error != null) {
            res.setException(error);
            return;
        }
        try {
            // This await should be very short; we're just forcing synchronization between this
            // block and the outer registration.setResult.
            ListenerRegistration actualRegistration = Tasks.await(registration.getTask());
            // Remove query first before passing event to user to avoid user actions affecting
            // the now stale query.
            actualRegistration.remove();
            if (snapshot.getMetadata().isFromCache() && source == Source.SERVER) {
                res.setException(new FirebaseFirestoreException("Failed to get documents from server. (However, these documents may " + "exist in the local cache. Run again without setting source to " + "SERVER to retrieve the cached documents.)", Code.UNAVAILABLE));
            } else {
                res.setResult(snapshot);
            }
        } catch (ExecutionException e) {
            throw fail(e, "Failed to register a listener for a query result");
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw fail(e, "Failed to register a listener for a query result");
        }
    });
    registration.setResult(listenerRegistration);
    return res.getTask();
}
Also used : TaskCompletionSource(com.google.android.gms.tasks.TaskCompletionSource) ListenOptions(com.google.firebase.firestore.core.EventManager.ListenOptions) ExecutionException(java.util.concurrent.ExecutionException)

Example 10 with ListenOptions

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

the class Query method internalOptions.

/**
 * Converts the public API options object to the internal options object.
 */
private static ListenOptions internalOptions(MetadataChanges metadataChanges) {
    ListenOptions internalOptions = new ListenOptions();
    internalOptions.includeDocumentMetadataChanges = (metadataChanges == MetadataChanges.INCLUDE);
    internalOptions.includeQueryMetadataChanges = (metadataChanges == MetadataChanges.INCLUDE);
    internalOptions.waitForSyncWhenOnline = false;
    return internalOptions;
}
Also used : ListenOptions(com.google.firebase.firestore.core.EventManager.ListenOptions)

Aggregations

ListenOptions (com.google.firebase.firestore.core.EventManager.ListenOptions)16 Test (org.junit.Test)9 ArrayList (java.util.ArrayList)8 MutableDocument (com.google.firebase.firestore.model.MutableDocument)6 TaskCompletionSource (com.google.android.gms.tasks.TaskCompletionSource)3 ExecutionException (java.util.concurrent.ExecutionException)3 NonNull (androidx.annotation.NonNull)2 QueryListener (com.google.firebase.firestore.core.QueryListener)2 Activity (android.app.Activity)1 Nullable (androidx.annotation.Nullable)1 Task (com.google.android.gms.tasks.Task)1 Tasks (com.google.android.gms.tasks.Tasks)1 FirebaseFirestoreException (com.google.firebase.firestore.FirebaseFirestoreException)1 Code (com.google.firebase.firestore.FirebaseFirestoreException.Code)1 ActivityScope (com.google.firebase.firestore.core.ActivityScope)1 AsyncEventListener (com.google.firebase.firestore.core.AsyncEventListener)1 ListenerRegistrationImpl (com.google.firebase.firestore.core.ListenerRegistrationImpl)1 Query (com.google.firebase.firestore.core.Query)1 ParsedSetData (com.google.firebase.firestore.core.UserData.ParsedSetData)1 ParsedUpdateData (com.google.firebase.firestore.core.UserData.ParsedUpdateData)1