Search in sources :

Example 1 with Timestamp

use of com.google.firebase.Timestamp in project firebase-android-sdk by firebase.

the class LocalStore method writeLocally.

/**
 * Accepts locally generated Mutations and commits them to storage.
 */
public LocalDocumentsResult writeLocally(List<Mutation> mutations) {
    Timestamp localWriteTime = Timestamp.now();
    // TODO: Call queryEngine.handleDocumentChange() appropriately.
    Set<DocumentKey> keys = new HashSet<>();
    for (Mutation mutation : mutations) {
        keys.add(mutation.getKey());
    }
    return persistence.runTransaction("Locally write mutations", () -> {
        // Load and apply all existing mutations. This lets us compute the current base state for
        // all non-idempotent transforms before applying any additional user-provided writes.
        ImmutableSortedMap<DocumentKey, Document> documents = localDocuments.getDocuments(keys);
        // For non-idempotent mutations (such as `FieldValue.increment()`), we record the base
        // state in a separate patch mutation. This is later used to guarantee consistent values
        // and prevents flicker even if the backend sends us an update that already includes our
        // transform.
        List<Mutation> baseMutations = new ArrayList<>();
        for (Mutation mutation : mutations) {
            ObjectValue baseValue = mutation.extractTransformBaseValue(documents.get(mutation.getKey()));
            if (baseValue != null) {
                // NOTE: The base state should only be applied if there's some existing
                // document to override, so use a Precondition of exists=true
                baseMutations.add(new PatchMutation(mutation.getKey(), baseValue, baseValue.getFieldMask(), Precondition.exists(true)));
            }
        }
        MutationBatch batch = mutationQueue.addMutationBatch(localWriteTime, baseMutations, mutations);
        Map<DocumentKey, Mutation> overlays = batch.applyToLocalDocumentSet(documents);
        documentOverlayCache.saveOverlays(batch.getBatchId(), overlays);
        return new LocalDocumentsResult(batch.getBatchId(), documents);
    });
}
Also used : ArrayList(java.util.ArrayList) Document(com.google.firebase.firestore.model.Document) MutableDocument(com.google.firebase.firestore.model.MutableDocument) Timestamp(com.google.firebase.Timestamp) ObjectValue(com.google.firebase.firestore.model.ObjectValue) MutationBatch(com.google.firebase.firestore.model.mutation.MutationBatch) DocumentKey(com.google.firebase.firestore.model.DocumentKey) PatchMutation(com.google.firebase.firestore.model.mutation.PatchMutation) PatchMutation(com.google.firebase.firestore.model.mutation.PatchMutation) Mutation(com.google.firebase.firestore.model.mutation.Mutation) HashSet(java.util.HashSet)

Example 2 with Timestamp

use of com.google.firebase.Timestamp in project firebase-android-sdk by firebase.

the class LocalSerializer method decodeMutationBatch.

/**
 * Decodes a WriteBatch proto into a MutationBatch model.
 */
MutationBatch decodeMutationBatch(com.google.firebase.firestore.proto.WriteBatch batch) {
    int batchId = batch.getBatchId();
    Timestamp localWriteTime = rpcSerializer.decodeTimestamp(batch.getLocalWriteTime());
    int baseMutationsCount = batch.getBaseWritesCount();
    List<Mutation> baseMutations = new ArrayList<>(baseMutationsCount);
    for (int i = 0; i < baseMutationsCount; i++) {
        baseMutations.add(rpcSerializer.decodeMutation(batch.getBaseWrites(i)));
    }
    List<Mutation> mutations = new ArrayList<>(batch.getWritesCount());
    // TODO(b/174608374): Remove this code once we perform a schema migration.
    for (int i = 0; i < batch.getWritesCount(); ++i) {
        Write currentMutation = batch.getWrites(i);
        boolean hasTransform = i + 1 < batch.getWritesCount() && batch.getWrites(i + 1).hasTransform();
        if (hasTransform) {
            hardAssert(batch.getWrites(i).hasUpdate(), "TransformMutation should be preceded by a patch or set mutation");
            Builder newMutationBuilder = Write.newBuilder(currentMutation);
            Write transformMutation = batch.getWrites(i + 1);
            for (FieldTransform fieldTransform : transformMutation.getTransform().getFieldTransformsList()) {
                newMutationBuilder.addUpdateTransforms(fieldTransform);
            }
            mutations.add(rpcSerializer.decodeMutation(newMutationBuilder.build()));
            ++i;
        } else {
            mutations.add(rpcSerializer.decodeMutation(currentMutation));
        }
    }
    return new MutationBatch(batchId, localWriteTime, baseMutations, mutations);
}
Also used : Write(com.google.firestore.v1.Write) MutationBatch(com.google.firebase.firestore.model.mutation.MutationBatch) Builder(com.google.firestore.v1.Write.Builder) FieldTransform(com.google.firestore.v1.DocumentTransform.FieldTransform) ArrayList(java.util.ArrayList) Mutation(com.google.firebase.firestore.model.mutation.Mutation) Timestamp(com.google.firebase.Timestamp)

Example 3 with Timestamp

use of com.google.firebase.Timestamp in project firebase-android-sdk by firebase.

the class SQLiteIndexManager method start.

@Override
public void start() {
    Map<Integer, FieldIndex.IndexState> indexStates = new HashMap<>();
    // Fetch all index states if persisted for the user. These states contain per user information
    // on how up to date the index is.
    db.query("SELECT index_id, sequence_number, read_time_seconds, read_time_nanos, document_key, " + "largest_batch_id FROM index_state WHERE uid = ?").binding(uid).forEach(row -> {
        int indexId = row.getInt(0);
        long sequenceNumber = row.getLong(1);
        SnapshotVersion readTime = new SnapshotVersion(new Timestamp(row.getLong(2), row.getInt(3)));
        DocumentKey documentKey = DocumentKey.fromPath(EncodedPath.decodeResourcePath(row.getString(4)));
        int largestBatchId = row.getInt(5);
        indexStates.put(indexId, FieldIndex.IndexState.create(sequenceNumber, readTime, documentKey, largestBatchId));
    });
    // Fetch all indices and combine with user's index state if available.
    db.query("SELECT index_id, collection_group, index_proto FROM index_configuration").forEach(row -> {
        try {
            int indexId = row.getInt(0);
            String collectionGroup = row.getString(1);
            List<FieldIndex.Segment> segments = serializer.decodeFieldIndexSegments(Index.parseFrom(row.getBlob(2)));
            // If we fetched an index state for the user above, combine it with this index.
            // We use the default state if we don't have an index state (e.g. the index was
            // created while a different user as logged in).
            FieldIndex.IndexState indexState = indexStates.containsKey(indexId) ? indexStates.get(indexId) : FieldIndex.INITIAL_STATE;
            FieldIndex fieldIndex = FieldIndex.create(indexId, collectionGroup, segments, indexState);
            // Store the index and update `memoizedMaxIndexId` and `memoizedMaxSequenceNumber`.
            memoizeIndex(fieldIndex);
        } catch (InvalidProtocolBufferException e) {
            throw fail("Failed to decode index: " + e);
        }
    });
    started = true;
}
Also used : FieldIndex(com.google.firebase.firestore.model.FieldIndex) HashMap(java.util.HashMap) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) Timestamp(com.google.firebase.Timestamp) SnapshotVersion(com.google.firebase.firestore.model.SnapshotVersion) DocumentKey(com.google.firebase.firestore.model.DocumentKey)

Example 4 with Timestamp

use of com.google.firebase.Timestamp in project firebase-android-sdk by firebase.

the class ServerTimestampTest method testPOJOSupport.

@Test
public void testPOJOSupport() {
    DocumentReference ref = testDocument();
    // Write empty pojo (nulls should turn into timestamps)
    TimestampPOJO pojo = new TimestampPOJO();
    waitFor(ref.set(pojo));
    // Read it back (timestamps should have been populated).
    pojo = waitFor(ref.get()).toObject(TimestampPOJO.class);
    assertNull(pojo.a);
    Timestamp resolvedTimestamp = pojo.timestamp1;
    assertNotNull(resolvedTimestamp);
    assertEquals(resolvedTimestamp, pojo.timestamp2);
    // Write it back; timestamps shouldn't change since they're non-null.
    pojo.a = 42L;
    waitFor(ref.set(pojo));
    // And read it back again; make sure the timestamps stayed the same.
    pojo = waitFor(ref.get()).toObject(TimestampPOJO.class);
    assertEquals((Long) 42L, pojo.a);
    assertEquals(resolvedTimestamp, pojo.timestamp1);
    assertEquals(resolvedTimestamp, pojo.timestamp2);
}
Also used : Timestamp(com.google.firebase.Timestamp) Test(org.junit.Test)

Example 5 with Timestamp

use of com.google.firebase.Timestamp in project firebase-android-sdk by firebase.

the class ServerTimestampTest method verifyTimestampsUsePreviousValue.

/**
 * Verifies a snapshot containing setData but using the previous field value for the timestamps.
 */
private void verifyTimestampsUsePreviousValue(DocumentSnapshot current, @Nullable DocumentSnapshot previous) {
    assertTrue(current.exists());
    if (previous != null) {
        Timestamp when = previous.getTimestamp("when");
        assertNotNull(when);
        assertEquals(expectedDataWithTimestamp(when), current.getData(ServerTimestampBehavior.PREVIOUS));
    } else {
        assertEquals(expectedDataWithTimestamp(null), current.getData(ServerTimestampBehavior.PREVIOUS));
    }
}
Also used : Timestamp(com.google.firebase.Timestamp)

Aggregations

Timestamp (com.google.firebase.Timestamp)36 Test (org.junit.Test)18 MutableDocument (com.google.firebase.firestore.model.MutableDocument)7 Date (java.util.Date)6 DocumentKey (com.google.firebase.firestore.model.DocumentKey)5 SnapshotVersion (com.google.firebase.firestore.model.SnapshotVersion)5 ArrayList (java.util.ArrayList)5 GeoPoint (com.google.firebase.firestore.GeoPoint)4 ObjectValue (com.google.firebase.firestore.model.ObjectValue)4 TestUtil.wrapObject (com.google.firebase.firestore.testutil.TestUtil.wrapObject)4 Mutation (com.google.firebase.firestore.model.mutation.Mutation)3 Mutation.calculateOverlayMutation (com.google.firebase.firestore.model.mutation.Mutation.calculateOverlayMutation)3 TestUtil.deleteMutation (com.google.firebase.firestore.testutil.TestUtil.deleteMutation)3 TestUtil.mergeMutation (com.google.firebase.firestore.testutil.TestUtil.mergeMutation)3 TestUtil.patchMutation (com.google.firebase.firestore.testutil.TestUtil.patchMutation)3 TestUtil.setMutation (com.google.firebase.firestore.testutil.TestUtil.setMutation)3 Value (com.google.firestore.v1.Value)3 HashMap (java.util.HashMap)3 FieldValue (com.google.firebase.firestore.FieldValue)2 Query (com.google.firebase.firestore.core.Query)2