diff --git a/dev/src/index.ts b/dev/src/index.ts index a70de3a84..791b2e4a7 100644 --- a/dev/src/index.ts +++ b/dev/src/index.ts @@ -432,6 +432,14 @@ export class Firestore implements firestore.Firestore { */ private _projectId: string | undefined = undefined; + /** + * The database ID provided via `.settings()`. + * + * @private + * @internal + */ + private _databaseId: string | undefined = undefined; + /** * Count of listeners that have been registered on the client. * @@ -571,6 +579,9 @@ export class Firestore implements firestore.Firestore { settings(settings: firestore.Settings): void { validateObject('settings', settings); validateString('settings.projectId', settings.projectId, {optional: true}); + validateString('settings.databaseId', settings.databaseId, { + optional: true, + }); if (this._settingsFrozen) { throw new Error( @@ -591,6 +602,11 @@ export class Firestore implements firestore.Firestore { this._projectId = settings.projectId; } + if (settings.databaseId !== undefined) { + validateString('settings.databaseId', settings.databaseId); + this._databaseId = settings.databaseId; + } + let url: URL | null = null; // If the environment variable is set, it should always take precedence @@ -678,6 +694,16 @@ export class Firestore implements firestore.Firestore { return this._projectId; } + /** + * Returns the Database ID for this Firestore instance. + * + * @private + * @internal + */ + get databaseId(): string { + return this._databaseId || DEFAULT_DATABASE_ID; + } + /** * Returns the root path of the database. Validates that * `initializeIfNeeded()` was called before. @@ -686,7 +712,7 @@ export class Firestore implements firestore.Firestore { * @internal */ get formattedName(): string { - return `projects/${this.projectId}/databases/${DEFAULT_DATABASE_ID}`; + return `projects/${this.projectId}/databases/${this.databaseId}`; } /** diff --git a/dev/test/index.ts b/dev/test/index.ts index a3cf866fe..96db12f8c 100644 --- a/dev/test/index.ts +++ b/dev/test/index.ts @@ -304,6 +304,7 @@ describe('instantiation', () => { /* eslint-disable @typescript-eslint/no-explicit-any */ expect((firestore as any)._settings.projectId).to.equal(PROJECT_ID); + expect((firestore as any)._settings.databaseId).to.be.undefined; expect((firestore as any)._settings.foo).to.equal('bar'); /* eslint-enable @typescript-eslint/no-explicit-any */ }); @@ -343,6 +344,23 @@ describe('instantiation', () => { ); }); + it('validates database ID is string', () => { + expect(() => { + const settings = {...DEFAULT_SETTINGS, databaseId: 1337}; + new Firestore.Firestore(settings as InvalidApiUsage); + }).to.throw( + 'Value for argument "settings.databaseId" is not a valid string.' + ); + + expect(() => { + new Firestore.Firestore(DEFAULT_SETTINGS).settings({ + databaseId: 1337, + } as InvalidApiUsage); + }).to.throw( + 'Value for argument "settings.databaseId" is not a valid string.' + ); + }); + it('validates ssl is a boolean', () => { const invalidValues = ['true', 1337]; @@ -548,11 +566,14 @@ describe('instantiation', () => { new Firestore.Firestore({maxIdleChannels: 1}); }); - it('uses project id from constructor', () => { - const firestore = new Firestore.Firestore({projectId: 'foo'}); + it('uses project id and database id from constructor', () => { + const firestore = new Firestore.Firestore({ + projectId: 'foo', + databaseId: 'bar', + }); return expect(firestore.formattedName).to.equal( - 'projects/foo/databases/(default)' + 'projects/foo/databases/bar' ); }); @@ -571,7 +592,7 @@ describe('instantiation', () => { }); }); - it('uses project ID from settings()', () => { + it('uses project ID from settings() and default database ID', () => { const firestore = new Firestore.Firestore({ sslCreds: grpc.credentials.createInsecure(), }); @@ -583,6 +604,18 @@ describe('instantiation', () => { ); }); + it('uses database ID and database ID from settings()', () => { + const firestore = new Firestore.Firestore({ + sslCreds: grpc.credentials.createInsecure(), + }); + + firestore.settings({projectId: PROJECT_ID, databaseId: 'bar'}); + + expect(firestore.formattedName).to.equal( + `projects/${PROJECT_ID}/databases/bar` + ); + }); + it('handles error from project ID detection', () => { return createInstance( { diff --git a/types/firestore.d.ts b/types/firestore.d.ts index 2e32bc40a..22e14e583 100644 --- a/types/firestore.d.ts +++ b/types/firestore.d.ts @@ -227,6 +227,13 @@ declare namespace FirebaseFirestore { */ projectId?: string; + /** + * The database name. If omitted, the default database will be used. + * + * @internal + */ + databaseId?: string; + /** The hostname to connect to. */ host?: string;