Skip to content

Commit 5509eaf

Browse files
author
Greg Soltis
authored
Add a custom error for schema downgrades, and a note about it (#1428)
* Add a custom error for schema downgrades, and a note about it
1 parent 6e89ddc commit 5509eaf

File tree

2 files changed

+48
-2
lines changed

2 files changed

+48
-2
lines changed

packages/firestore/src/local/simple_db.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,14 @@ export interface SimpleDbSchemaConverter {
4141
* See PersistencePromise for more details.
4242
*/
4343
export class SimpleDb {
44-
/** Opens the specified database, creating or upgrading it if necessary. */
44+
/**
45+
* Opens the specified database, creating or upgrading it if necessary.
46+
*
47+
* Note that `version` must not be a downgrade. IndexedDB does not support downgrading the schema
48+
* version. We currently do not support any way to do versioning outside of IndexedDB's versioning
49+
* mechanism, as only version-upgrade transactions are allowed to do things like create
50+
* objectstores.
51+
*/
4552
static openOrCreate(
4653
name: string,
4754
version: number,
@@ -76,7 +83,21 @@ export class SimpleDb {
7683
};
7784

7885
request.onerror = (event: Event) => {
79-
reject((event.target as IDBOpenDBRequest).error);
86+
const error: DOMException = (event.target as IDBOpenDBRequest).error!;
87+
if (error.name === 'VersionError') {
88+
reject(
89+
new FirestoreError(
90+
Code.FAILED_PRECONDITION,
91+
'A newer version of the Firestore SDK was previously used and so the persisted ' +
92+
'data is not compatible with the version of the SDK you are now using. The SDK ' +
93+
'will operate with persistence disabled. If you need persistence, please ' +
94+
're-upgrade to a newer version of the SDK or else clear the persisted IndexedDB ' +
95+
'data for your app to start fresh.'
96+
)
97+
);
98+
} else {
99+
reject(error);
100+
}
80101
};
81102

82103
request.onupgradeneeded = (event: IDBVersionChangeEvent) => {

packages/firestore/test/unit/local/indexeddb_persistence.test.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import { SimpleDb, SimpleDbTransaction } from '../../../src/local/simple_db';
5252
import { PlatformSupport } from '../../../src/platform/platform';
5353
import { JsonProtoSerializer } from '../../../src/remote/serializer';
5454
import { AsyncQueue } from '../../../src/util/async_queue';
55+
import { FirestoreError } from '../../../src/util/error';
5556
import { doc, path } from '../../util/helpers';
5657
import { SharedFakeWebStorage, TestPlatform } from '../../util/test_platform';
5758
import {
@@ -602,6 +603,30 @@ describe('IndexedDbSchema: createOrUpgradeDb', () => {
602603
});
603604
});
604605
});
606+
607+
it('downgrading throws a custom error', async () => {
608+
// Upgrade to latest version
609+
await withDb(SCHEMA_VERSION, async db => {
610+
expect(db.version).to.equal(SCHEMA_VERSION);
611+
});
612+
// downgrade by one version
613+
const downgradeVersion = SCHEMA_VERSION - 1;
614+
const schemaConverter = new SchemaConverter(TEST_SERIALIZER);
615+
let error: FirestoreError | null = null;
616+
try {
617+
await SimpleDb.openOrCreate(
618+
INDEXEDDB_TEST_DATABASE_NAME,
619+
downgradeVersion,
620+
schemaConverter
621+
);
622+
} catch (e) {
623+
error = e;
624+
expect(
625+
e.message.indexOf('A newer version of the Firestore SDK')
626+
).to.not.equal(-1);
627+
}
628+
expect(error).to.not.be.null;
629+
});
605630
});
606631

607632
describe('IndexedDb: canActAsPrimary', () => {

0 commit comments

Comments
 (0)