diff --git a/packages/firestore/src/local/indexeddb_persistence.ts b/packages/firestore/src/local/indexeddb_persistence.ts index 950994cf1f5..a60d3dc883d 100644 --- a/packages/firestore/src/local/indexeddb_persistence.ts +++ b/packages/firestore/src/local/indexeddb_persistence.ts @@ -440,15 +440,30 @@ export class IndexedDbPersistence implements Persistence { } getMutationQueue(user: User): MutationQueue { + assert( + this.started, + 'Cannot initialize MutationQueue before persistence is started.' + ); return IndexedDbMutationQueue.forUser(user, this.serializer); } getQueryCache(): QueryCache { + assert( + this.started, + 'Cannot initialize QueryCache before persistence is started.' + ); return new IndexedDbQueryCache(this.serializer); } getRemoteDocumentCache(): RemoteDocumentCache { - return new IndexedDbRemoteDocumentCache(this.serializer); + assert( + this.started, + 'Cannot initialize RemoteDocumentCache before persistence is started.' + ); + return new IndexedDbRemoteDocumentCache( + this.serializer, + /*keepDocumentChangeLog=*/ this.allowTabSynchronization + ); } runTransaction( diff --git a/packages/firestore/src/local/indexeddb_remote_document_cache.ts b/packages/firestore/src/local/indexeddb_remote_document_cache.ts index d05ea4110ea..ef4bebdea80 100644 --- a/packages/firestore/src/local/indexeddb_remote_document_cache.ts +++ b/packages/firestore/src/local/indexeddb_remote_document_cache.ts @@ -37,12 +37,23 @@ import { PersistencePromise } from './persistence_promise'; import { RemoteDocumentCache } from './remote_document_cache'; import { SimpleDb, SimpleDbStore } from './simple_db'; import { SnapshotVersion } from '../core/snapshot_version'; +import { assert } from '../util/assert'; export class IndexedDbRemoteDocumentCache implements RemoteDocumentCache { /** The last id read by `getNewDocumentChanges()`. */ private lastReturnedDocumentChangesId = 0; - constructor(private serializer: LocalSerializer) {} + /** + * @param {LocalSerializer} serializer The document serializer. + * @param keepDocumentChangeLog Whether to keep a document change log in + * IndexedDb. This change log is required for Multi-Tab synchronization, but + * not needed in clients that don't share access to their remote document + * cache. + */ + constructor( + private readonly serializer: LocalSerializer, + private readonly keepDocumentChangeLog: boolean + ) {} start(transaction: PersistenceTransaction): PersistencePromise { // If there are no existing changes, we set `lastReturnedDocumentChangesId` @@ -77,11 +88,14 @@ export class IndexedDbRemoteDocumentCache implements RemoteDocumentCache { changedKeys = changedKeys.add(maybeDocument.key); } - promises.push( - documentChangesStore(transaction).put({ - changes: this.serializer.toDbResourcePaths(changedKeys) - }) - ); + if (this.keepDocumentChangeLog) { + // TODO(multitab): GC the documentChanges store. + promises.push( + documentChangesStore(transaction).put({ + changes: this.serializer.toDbResourcePaths(changedKeys) + }) + ); + } } return PersistencePromise.waitFor(promises); @@ -134,6 +148,10 @@ export class IndexedDbRemoteDocumentCache implements RemoteDocumentCache { getNewDocumentChanges( transaction: PersistenceTransaction ): PersistencePromise { + assert( + this.keepDocumentChangeLog, + 'Can only call getNewDocumentChanges() when document change log is enabled' + ); let changedKeys = documentKeySet(); let changedDocs = maybeDocumentMap(); diff --git a/packages/firestore/test/unit/local/persistence_test_helpers.ts b/packages/firestore/test/unit/local/persistence_test_helpers.ts index 471bd377076..9c90707d5f3 100644 --- a/packages/firestore/test/unit/local/persistence_test_helpers.ts +++ b/packages/firestore/test/unit/local/persistence_test_helpers.ts @@ -51,12 +51,10 @@ const LOCAL_STORAGE_PREFIX = 'firestore_'; * any previous contents if they existed. */ export async function testIndexedDbPersistence( - queue?: AsyncQueue, - clientId?: ClientId + synchronizeTabs?: boolean ): Promise { - queue = queue || new AsyncQueue(); - clientId = clientId || AutoId.newId(); - + const queue = new AsyncQueue(); + const clientId = AutoId.newId(); const prefix = `${TEST_PERSISTENCE_PREFIX}/`; await SimpleDb.delete(prefix + IndexedDbPersistence.MAIN_DATABASE); const partition = new DatabaseId('project'); @@ -71,7 +69,7 @@ export async function testIndexedDbPersistence( queue, serializer ); - await persistence.start(); + await persistence.start(synchronizeTabs); return persistence; } diff --git a/packages/firestore/test/unit/local/remote_document_cache.test.ts b/packages/firestore/test/unit/local/remote_document_cache.test.ts index 98ad272df5c..59491cc0bac 100644 --- a/packages/firestore/test/unit/local/remote_document_cache.test.ts +++ b/packages/firestore/test/unit/local/remote_document_cache.test.ts @@ -52,9 +52,12 @@ describe('IndexedDbRemoteDocumentCache', () => { } beforeEach(() => { - return persistenceHelpers.testIndexedDbPersistence().then(p => { - persistence = p; - }); + // We turn on `synchronizeTabs` to test the document change log. + return persistenceHelpers + .testIndexedDbPersistence(/* synchronizeTabs= */ true) + .then(p => { + persistence = p; + }); }); afterEach(() => persistence.shutdown(/* deleteData= */ true));