Search in sources :

Example 16 with WatchTargetChange

use of com.google.firebase.firestore.remote.WatchChange.WatchTargetChange in project firebase-android-sdk by firebase.

the class RemoteStore method handleWatchChange.

private void handleWatchChange(SnapshotVersion snapshotVersion, WatchChange watchChange) {
    // Mark the connection as ONLINE because we got a message from the server.
    onlineStateTracker.updateState(OnlineState.ONLINE);
    hardAssert((watchStream != null) && (watchChangeAggregator != null), "WatchStream and WatchStreamAggregator should both be non-null");
    WatchTargetChange watchTargetChange = watchChange instanceof WatchTargetChange ? (WatchTargetChange) watchChange : null;
    if (watchTargetChange != null && watchTargetChange.getChangeType().equals(WatchTargetChangeType.Removed) && watchTargetChange.getCause() != null) {
        // There was an error on a target, don't wait for a consistent snapshot to raise events
        processTargetError(watchTargetChange);
    } else {
        if (watchChange instanceof DocumentChange) {
            watchChangeAggregator.handleDocumentChange((DocumentChange) watchChange);
        } else if (watchChange instanceof ExistenceFilterWatchChange) {
            watchChangeAggregator.handleExistenceFilter((ExistenceFilterWatchChange) watchChange);
        } else {
            hardAssert(watchChange instanceof WatchTargetChange, "Expected watchChange to be an instance of WatchTargetChange");
            watchChangeAggregator.handleTargetChange((WatchTargetChange) watchChange);
        }
        if (!snapshotVersion.equals(SnapshotVersion.NONE)) {
            SnapshotVersion lastRemoteSnapshotVersion = this.localStore.getLastRemoteSnapshotVersion();
            if (snapshotVersion.compareTo(lastRemoteSnapshotVersion) >= 0) {
                // We have received a target change with a global snapshot if the snapshot
                // version is not equal to SnapshotVersion.MIN.
                raiseWatchSnapshot(snapshotVersion);
            }
        }
    }
}
Also used : SnapshotVersion(com.google.firebase.firestore.model.SnapshotVersion) DocumentChange(com.google.firebase.firestore.remote.WatchChange.DocumentChange) ExistenceFilterWatchChange(com.google.firebase.firestore.remote.WatchChange.ExistenceFilterWatchChange) WatchTargetChange(com.google.firebase.firestore.remote.WatchChange.WatchTargetChange)

Example 17 with WatchTargetChange

use of com.google.firebase.firestore.remote.WatchChange.WatchTargetChange in project firebase-android-sdk by firebase.

the class RemoteSerializer method decodeWatchChange.

// Watch changes
public WatchChange decodeWatchChange(ListenResponse protoChange) {
    WatchChange watchChange;
    switch(protoChange.getResponseTypeCase()) {
        case TARGET_CHANGE:
            com.google.firestore.v1.TargetChange targetChange = protoChange.getTargetChange();
            WatchTargetChangeType changeType;
            Status cause = null;
            switch(targetChange.getTargetChangeType()) {
                case NO_CHANGE:
                    changeType = WatchTargetChangeType.NoChange;
                    break;
                case ADD:
                    changeType = WatchTargetChangeType.Added;
                    break;
                case REMOVE:
                    changeType = WatchTargetChangeType.Removed;
                    cause = fromStatus(targetChange.getCause());
                    break;
                case CURRENT:
                    changeType = WatchTargetChangeType.Current;
                    break;
                case RESET:
                    changeType = WatchTargetChangeType.Reset;
                    break;
                case UNRECOGNIZED:
                default:
                    throw new IllegalArgumentException("Unknown target change type");
            }
            watchChange = new WatchTargetChange(changeType, targetChange.getTargetIdsList(), targetChange.getResumeToken(), cause);
            break;
        case DOCUMENT_CHANGE:
            DocumentChange docChange = protoChange.getDocumentChange();
            List<Integer> added = docChange.getTargetIdsList();
            List<Integer> removed = docChange.getRemovedTargetIdsList();
            DocumentKey key = decodeKey(docChange.getDocument().getName());
            SnapshotVersion version = decodeVersion(docChange.getDocument().getUpdateTime());
            hardAssert(!version.equals(SnapshotVersion.NONE), "Got a document change without an update time");
            ObjectValue data = ObjectValue.fromMap(docChange.getDocument().getFieldsMap());
            MutableDocument document = MutableDocument.newFoundDocument(key, version, data);
            watchChange = new WatchChange.DocumentChange(added, removed, document.getKey(), document);
            break;
        case DOCUMENT_DELETE:
            DocumentDelete docDelete = protoChange.getDocumentDelete();
            removed = docDelete.getRemovedTargetIdsList();
            key = decodeKey(docDelete.getDocument());
            // Note that version might be unset in which case we use SnapshotVersion.NONE
            version = decodeVersion(docDelete.getReadTime());
            MutableDocument doc = MutableDocument.newNoDocument(key, version);
            watchChange = new WatchChange.DocumentChange(Collections.emptyList(), removed, doc.getKey(), doc);
            break;
        case DOCUMENT_REMOVE:
            DocumentRemove docRemove = protoChange.getDocumentRemove();
            removed = docRemove.getRemovedTargetIdsList();
            key = decodeKey(docRemove.getDocument());
            watchChange = new WatchChange.DocumentChange(Collections.emptyList(), removed, key, null);
            break;
        case FILTER:
            com.google.firestore.v1.ExistenceFilter protoFilter = protoChange.getFilter();
            // TODO: implement existence filter parsing (see b/33076578)
            ExistenceFilter filter = new ExistenceFilter(protoFilter.getCount());
            int targetId = protoFilter.getTargetId();
            watchChange = new ExistenceFilterWatchChange(targetId, filter);
            break;
        case RESPONSETYPE_NOT_SET:
        default:
            throw new IllegalArgumentException("Unknown change type set");
    }
    return watchChange;
}
Also used : Status(io.grpc.Status) DocumentRemove(com.google.firestore.v1.DocumentRemove) MutableDocument(com.google.firebase.firestore.model.MutableDocument) WatchTargetChangeType(com.google.firebase.firestore.remote.WatchChange.WatchTargetChangeType) DocumentChange(com.google.firestore.v1.DocumentChange) WatchTargetChange(com.google.firebase.firestore.remote.WatchChange.WatchTargetChange) DocumentDelete(com.google.firestore.v1.DocumentDelete) ObjectValue(com.google.firebase.firestore.model.ObjectValue) SnapshotVersion(com.google.firebase.firestore.model.SnapshotVersion) ExistenceFilterWatchChange(com.google.firebase.firestore.remote.WatchChange.ExistenceFilterWatchChange) DocumentKey(com.google.firebase.firestore.model.DocumentKey) ExistenceFilterWatchChange(com.google.firebase.firestore.remote.WatchChange.ExistenceFilterWatchChange)

Example 18 with WatchTargetChange

use of com.google.firebase.firestore.remote.WatchChange.WatchTargetChange in project firebase-android-sdk by firebase.

the class RemoteEventTest method testResumeTokenHandledPerTarget.

@Test
public void testResumeTokenHandledPerTarget() {
    Map<Integer, TargetData> targetMap = activeQueries(1, 2);
    WatchChangeAggregator aggregator = createAggregator(targetMap, noOutstandingResponses, noExistingKeys);
    WatchTargetChange change1 = new WatchTargetChange(WatchTargetChangeType.Current, asList(1));
    aggregator.handleTargetChange(change1);
    ByteString resumeToken2 = ByteString.copyFromUtf8("resumeToken2");
    WatchTargetChange change2 = new WatchTargetChange(WatchTargetChangeType.Current, asList(2), resumeToken2);
    aggregator.handleTargetChange(change2);
    RemoteEvent event = aggregator.createRemoteEvent(version(3));
    assertEquals(2, event.getTargetChanges().size());
    TargetChange mapping1 = targetChange(resumeToken, true, null, null, null);
    assertEquals(mapping1, event.getTargetChanges().get(1));
    TargetChange mapping2 = targetChange(resumeToken2, true, null, null, null);
    assertEquals(mapping2, event.getTargetChanges().get(2));
}
Also used : TargetData(com.google.firebase.firestore.local.TargetData) WatchTargetChange(com.google.firebase.firestore.remote.WatchChange.WatchTargetChange) ByteString(com.google.protobuf.ByteString) WatchTargetChange(com.google.firebase.firestore.remote.WatchChange.WatchTargetChange) Test(org.junit.Test)

Example 19 with WatchTargetChange

use of com.google.firebase.firestore.remote.WatchChange.WatchTargetChange in project firebase-android-sdk by firebase.

the class RemoteEventTest method testDoesNotSynthesizeDeleteWithExistingDocument.

@Test
public void testDoesNotSynthesizeDeleteWithExistingDocument() {
    Map<Integer, TargetData> targetMap = activeLimboQueries("foo/doc", 1);
    WatchTargetChange hasDocument = new WatchTargetChange(WatchTargetChangeType.Current, asList(1));
    RemoteEvent event = createRemoteEvent(3, targetMap, noOutstandingResponses, keySet(key("foo/doc")), hasDocument);
    assertEquals(0, event.getDocumentUpdates().size());
    assertEquals(0, event.getResolvedLimboDocuments().size());
}
Also used : TargetData(com.google.firebase.firestore.local.TargetData) WatchTargetChange(com.google.firebase.firestore.remote.WatchChange.WatchTargetChange) Test(org.junit.Test)

Example 20 with WatchTargetChange

use of com.google.firebase.firestore.remote.WatchChange.WatchTargetChange in project firebase-android-sdk by firebase.

the class RemoteEventTest method testWillIgnoreEventsForRemovedTargets.

@Test
public void testWillIgnoreEventsForRemovedTargets() {
    Map<Integer, TargetData> targetMap = activeQueries();
    MutableDocument doc1 = doc("docs/1", 1, map("value", 1));
    // We're waiting for the unwatch ack
    Map<Integer, Integer> outstanding = new HashMap<>();
    outstanding.put(1, 1);
    WatchChange change1 = new DocumentChange(asList(1), emptyList(), doc1.getKey(), doc1);
    WatchChange change2 = new WatchTargetChange(WatchTargetChangeType.Removed, asList(1));
    RemoteEvent event = createRemoteEvent(3, targetMap, outstanding, noExistingKeys, change1, change2);
    assertEquals(version(3), event.getSnapshotVersion());
    // doc1 is ignored because it was not apart of an active target.
    assertEquals(0, event.getDocumentUpdates().size());
    // Target 1 is ignored because it was removed
    assertEquals(0, event.getTargetChanges().size());
}
Also used : TargetData(com.google.firebase.firestore.local.TargetData) HashMap(java.util.HashMap) MutableDocument(com.google.firebase.firestore.model.MutableDocument) DocumentChange(com.google.firebase.firestore.remote.WatchChange.DocumentChange) WatchTargetChange(com.google.firebase.firestore.remote.WatchChange.WatchTargetChange) Test(org.junit.Test)

Aggregations

WatchTargetChange (com.google.firebase.firestore.remote.WatchChange.WatchTargetChange)26 Test (org.junit.Test)18 TargetData (com.google.firebase.firestore.local.TargetData)16 MutableDocument (com.google.firebase.firestore.model.MutableDocument)9 DocumentChange (com.google.firebase.firestore.remote.WatchChange.DocumentChange)9 ExistenceFilterWatchChange (com.google.firebase.firestore.remote.WatchChange.ExistenceFilterWatchChange)4 ByteString (com.google.protobuf.ByteString)4 HashMap (java.util.HashMap)4 DocumentKey (com.google.firebase.firestore.model.DocumentKey)3 SnapshotVersion (com.google.firebase.firestore.model.SnapshotVersion)2 WatchChange (com.google.firebase.firestore.remote.WatchChange)2 Status (io.grpc.Status)2 ObjectValue (com.google.firebase.firestore.model.ObjectValue)1 WatchTargetChangeType (com.google.firebase.firestore.remote.WatchChange.WatchTargetChangeType)1 DocumentChange (com.google.firestore.v1.DocumentChange)1 DocumentDelete (com.google.firestore.v1.DocumentDelete)1 DocumentRemove (com.google.firestore.v1.DocumentRemove)1 ArrayList (java.util.ArrayList)1 Map (java.util.Map)1 JSONObject (org.json.JSONObject)1