Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save schmidt-sebastian/d51c9c9ec7be723fc8f208d69c4bbd9f to your computer and use it in GitHub Desktop.
Save schmidt-sebastian/d51c9c9ec7be723fc8f208d69c4bbd9f to your computer and use it in GitHub Desktop.
diff --git a/packages/firestore/src/core/bundle.ts b/packages/firestore/src/core/bundle.ts
index adba7f725..90dd394fe 100644
--- a/packages/firestore/src/core/bundle.ts
+++ b/packages/firestore/src/core/bundle.ts
@@ -83,7 +83,7 @@ export type BundledDocuments = BundledDocument[];
* Helper to convert objects from bundles to model objects in the SDK.
*/
export class BundleConverter {
- constructor(private serializer: JsonProtoSerializer) {}
+ constructor(private readonly serializer: JsonProtoSerializer) {}
toDocumentKey(name: string): DocumentKey {
return fromName(this.serializer, name);
@@ -165,7 +165,8 @@ export class BundleLoader {
constructor(
private metadata: bundleProto.BundleMetadata,
- private localStore: LocalStore
+ private localStore: LocalStore,
+ private serializer: JsonProtoSerializer
) {
this.progress = bundleInitialProgress(metadata);
}
@@ -217,7 +218,7 @@ export class BundleLoader {
): Map<string, DocumentKeySet> {
const queryDocumentMap = new Map<string, DocumentKeySet>();
const bundleConverter = new BundleConverter(
- this.localStore.getSerializer()
+ this.serializer
);
for (const bundleDoc of documents) {
if (bundleDoc.metadata.queries) {
diff --git a/packages/firestore/src/core/firestore_client.ts b/packages/firestore/src/core/firestore_client.ts
index 1972d8395..70373b318 100644
--- a/packages/firestore/src/core/firestore_client.ts
+++ b/packages/firestore/src/core/firestore_client.ts
@@ -55,9 +55,10 @@ import { TransactionRunner } from './transaction_runner';
import { Datastore } from '../remote/datastore';
import { BundleReader } from '../util/bundle_reader';
import { LoadBundleTask } from '../api/bundle';
-import { newTextEncoder } from '../platform/serializer';
+import {newSerializer, newTextEncoder} from '../platform/serializer';
import { toByteStreamReader } from '../platform/byte_stream_reader';
import { NamedQuery } from './bundle';
+import {JsonProtoSerializer} from "../remote/serializer";
const LOG_TAG = 'FirestoreClient';
export const MAX_CONCURRENT_LIMBO_RESOLUTIONS = 100;
@@ -537,7 +538,7 @@ export class FirestoreClient {
): void {
this.verifyNotTerminated();
- const reader = createBundleReader(data);
+ const reader = createBundleReader(data, newSerializer(this.databaseInfo.databaseId));
this.asyncQueue.enqueueAndForget(async () => {
loadBundle(this.syncEngine, reader, resultTask);
return resultTask.catch(e => {
@@ -798,7 +799,8 @@ export function enqueueExecuteQueryViaSnapshotListener(
}
function createBundleReader(
- data: ReadableStream<Uint8Array> | ArrayBuffer | string
+ data: ReadableStream<Uint8Array> | ArrayBuffer | string,
+ serializer: JsonProtoSerializer
): BundleReader {
let content: ReadableStream<Uint8Array> | ArrayBuffer;
if (typeof data === 'string') {
@@ -806,7 +808,7 @@ function createBundleReader(
} else {
content = data;
}
- return new BundleReader(toByteStreamReader(content));
+ return new BundleReader(toByteStreamReader(content), serializer);
}
export function enqueueLoadBundle(
diff --git a/packages/firestore/src/core/sync_engine.ts b/packages/firestore/src/core/sync_engine.ts
index 2dd5c81ab..79cc98c37 100644
--- a/packages/firestore/src/core/sync_engine.ts
+++ b/packages/firestore/src/core/sync_engine.ts
@@ -1358,7 +1358,7 @@ async function loadBundleImpl(
task._updateProgress(bundleInitialProgress(metadata));
- const loader = new BundleLoader(metadata, syncEngine.localStore);
+ const loader = new BundleLoader(metadata, syncEngine.localStore, reader.serializer);
let element = await reader.nextElement();
while (element) {
debugAssert(
diff --git a/packages/firestore/src/local/local_store.ts b/packages/firestore/src/local/local_store.ts
index 9fd35743c..420e2b7a4 100644
--- a/packages/firestore/src/local/local_store.ts
+++ b/packages/firestore/src/local/local_store.ts
@@ -277,9 +277,6 @@ export interface LocalStore {
executeQuery(query: Query, usePreviousResults: boolean): Promise<QueryResult>;
collectGarbage(garbageCollector: LruGarbageCollector): Promise<LruResults>;
-
- /** Returns the serializer associated with the local store. */
- getSerializer(): JsonProtoSerializer;
}
/**
@@ -1086,10 +1083,6 @@ class LocalStoreImpl implements LocalStore {
txn => garbageCollector.collect(txn, this.targetDataByTarget)
);
}
-
- getSerializer(): JsonProtoSerializer {
- return this.serializer;
- }
}
export function newLocalStore(
@@ -1391,42 +1384,43 @@ export async function saveNamedQuery(
const allocated = await localStore.allocateTarget(
queryToTarget(fromBundledQuery(query.bundledQuery!))
);
+
+ const readTime = fromVersion(query.readTime!);
+ // Don't update allocated target's read time if the bundle's read time is
+ // older.
+ if (allocated.snapshotVersion.compareTo(readTime) >= 0) {
+ return;
+ }
+
const localStoreImpl = debugCast(localStore, LocalStoreImpl);
return localStoreImpl.persistence.runTransaction(
'Save named query',
'readwrite',
transaction => {
- // Update allocated target's read time, if the bundle's read time is newer.
- let readTimeUpdated = PersistencePromise.resolve();
- const readTime = fromVersion(query.readTime!);
- if (allocated.snapshotVersion.compareTo(readTime) < 0) {
- const newTargetData = allocated.withResumeToken(
- ByteString.EMPTY_BYTE_STRING,
- readTime
- );
- readTimeUpdated = localStoreImpl.targetCache
- .updateTargetData(transaction, newTargetData)
- .next(() =>
- localStoreImpl.targetCache.removeMatchingKeysForTargetId(
- transaction,
- allocated.targetId
- )
- )
- .next(() =>
- localStoreImpl.targetCache.addMatchingKeys(
- transaction,
- documents,
- allocated.targetId
- )
- );
- localStoreImpl.targetDataByTarget = localStoreImpl.targetDataByTarget.insert(
- newTargetData.targetId,
- newTargetData
- );
- }
- return readTimeUpdated.next(() =>
- localStoreImpl.bundleCache.saveNamedQuery(transaction, query)
+ const newTargetData = allocated.withResumeToken(
+ ByteString.EMPTY_BYTE_STRING,
+ readTime
);
- }
- );
+ localStoreImpl.targetDataByTarget = localStoreImpl.targetDataByTarget.insert(
+ newTargetData.targetId,
+ newTargetData
+ );
+ return localStoreImpl.targetCache
+ .updateTargetData(transaction, newTargetData)
+ .next(() =>
+ localStoreImpl.targetCache.removeMatchingKeysForTargetId(
+ transaction,
+ allocated.targetId
+ )
+ )
+ .next(() =>
+ localStoreImpl.targetCache.addMatchingKeys(
+ transaction,
+ documents,
+ allocated.targetId
+ )
+ ).next(() =>
+ localStoreImpl.bundleCache.saveNamedQuery(transaction, query)
+ )
+ });
}
diff --git a/packages/firestore/src/util/bundle_reader.ts b/packages/firestore/src/util/bundle_reader.ts
index d2e9c23ac..c9e2741a8 100644
--- a/packages/firestore/src/util/bundle_reader.ts
+++ b/packages/firestore/src/util/bundle_reader.ts
@@ -23,6 +23,7 @@ import { Deferred } from './promise';
import { debugAssert } from './assert';
import { toByteStreamReader } from '../platform/byte_stream_reader';
import { newTextDecoder } from '../platform/serializer';
+import {JsonProtoSerializer} from "../remote/serializer";
/**
* A complete element in the bundle stream, together with the byte length it
@@ -70,13 +71,14 @@ export class BundleReader {
/** The decoder used to parse binary data into strings. */
private textDecoder: TextDecoder;
- static fromBundleSource(source: BundleSource): BundleReader {
- return new BundleReader(toByteStreamReader(source, BYTES_PER_READ));
+ static fromBundleSource(source: BundleSource, serializer: JsonProtoSerializer): BundleReader {
+ return new BundleReader(toByteStreamReader(source, BYTES_PER_READ), serializer);
}
constructor(
/** The reader to read from underlying binary bundle data source. */
- private reader: ReadableStreamReader<Uint8Array>
+ private reader: ReadableStreamReader<Uint8Array>,
+ readonly serializer: JsonProtoSerializer
) {
this.textDecoder = newTextDecoder();
// Read the metadata (which is the first element).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment