Skip to content
This repository was archived by the owner on Mar 4, 2026. It is now read-only.

Commit 5ba8df0

Browse files
authored
feat: Add internal multi-db support (#1761)
1 parent 07181e2 commit 5ba8df0

3 files changed

Lines changed: 71 additions & 5 deletions

File tree

dev/src/index.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,14 @@ export class Firestore implements firestore.Firestore {
444444
*/
445445
private _projectId: string | undefined = undefined;
446446

447+
/**
448+
* The database ID provided via `.settings()`.
449+
*
450+
* @private
451+
* @internal
452+
*/
453+
private _databaseId: string | undefined = undefined;
454+
447455
/**
448456
* Count of listeners that have been registered on the client.
449457
*
@@ -612,6 +620,9 @@ export class Firestore implements firestore.Firestore {
612620
settings(settings: firestore.Settings): void {
613621
validateObject('settings', settings);
614622
validateString('settings.projectId', settings.projectId, {optional: true});
623+
validateString('settings.databaseId', settings.databaseId, {
624+
optional: true,
625+
});
615626

616627
if (this._settingsFrozen) {
617628
throw new Error(
@@ -632,6 +643,11 @@ export class Firestore implements firestore.Firestore {
632643
this._projectId = settings.projectId;
633644
}
634645

646+
if (settings.databaseId !== undefined) {
647+
validateString('settings.databaseId', settings.databaseId);
648+
this._databaseId = settings.databaseId;
649+
}
650+
635651
let url: URL | null = null;
636652

637653
// If the environment variable is set, it should always take precedence
@@ -719,6 +735,16 @@ export class Firestore implements firestore.Firestore {
719735
return this._projectId;
720736
}
721737

738+
/**
739+
* Returns the Database ID for this Firestore instance.
740+
*
741+
* @private
742+
* @internal
743+
*/
744+
get databaseId(): string {
745+
return this._databaseId || DEFAULT_DATABASE_ID;
746+
}
747+
722748
/**
723749
* Returns the root path of the database. Validates that
724750
* `initializeIfNeeded()` was called before.
@@ -727,7 +753,7 @@ export class Firestore implements firestore.Firestore {
727753
* @internal
728754
*/
729755
get formattedName(): string {
730-
return `projects/${this.projectId}/databases/${DEFAULT_DATABASE_ID}`;
756+
return `projects/${this.projectId}/databases/${this.databaseId}`;
731757
}
732758

733759
/**

dev/test/index.ts

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@ describe('instantiation', () => {
304304

305305
/* eslint-disable @typescript-eslint/no-explicit-any */
306306
expect((firestore as any)._settings.projectId).to.equal(PROJECT_ID);
307+
expect((firestore as any)._settings.databaseId).to.be.undefined;
307308
expect((firestore as any)._settings.foo).to.equal('bar');
308309
/* eslint-enable @typescript-eslint/no-explicit-any */
309310
});
@@ -343,6 +344,23 @@ describe('instantiation', () => {
343344
);
344345
});
345346

347+
it('validates database ID is string', () => {
348+
expect(() => {
349+
const settings = {...DEFAULT_SETTINGS, databaseId: 1337};
350+
new Firestore.Firestore(settings as InvalidApiUsage);
351+
}).to.throw(
352+
'Value for argument "settings.databaseId" is not a valid string.'
353+
);
354+
355+
expect(() => {
356+
new Firestore.Firestore(DEFAULT_SETTINGS).settings({
357+
databaseId: 1337,
358+
} as InvalidApiUsage);
359+
}).to.throw(
360+
'Value for argument "settings.databaseId" is not a valid string.'
361+
);
362+
});
363+
346364
it('validates ssl is a boolean', () => {
347365
const invalidValues = ['true', 1337];
348366

@@ -548,11 +566,14 @@ describe('instantiation', () => {
548566
new Firestore.Firestore({maxIdleChannels: 1});
549567
});
550568

551-
it('uses project id from constructor', () => {
552-
const firestore = new Firestore.Firestore({projectId: 'foo'});
569+
it('uses project id and database id from constructor', () => {
570+
const firestore = new Firestore.Firestore({
571+
projectId: 'foo',
572+
databaseId: 'bar',
573+
});
553574

554575
return expect(firestore.formattedName).to.equal(
555-
'projects/foo/databases/(default)'
576+
'projects/foo/databases/bar'
556577
);
557578
});
558579

@@ -571,7 +592,7 @@ describe('instantiation', () => {
571592
});
572593
});
573594

574-
it('uses project ID from settings()', () => {
595+
it('uses project ID from settings() and default database ID', () => {
575596
const firestore = new Firestore.Firestore({
576597
sslCreds: grpc.credentials.createInsecure(),
577598
});
@@ -583,6 +604,18 @@ describe('instantiation', () => {
583604
);
584605
});
585606

607+
it('uses database ID and database ID from settings()', () => {
608+
const firestore = new Firestore.Firestore({
609+
sslCreds: grpc.credentials.createInsecure(),
610+
});
611+
612+
firestore.settings({projectId: PROJECT_ID, databaseId: 'bar'});
613+
614+
expect(firestore.formattedName).to.equal(
615+
`projects/${PROJECT_ID}/databases/bar`
616+
);
617+
});
618+
586619
it('handles error from project ID detection', () => {
587620
return createInstance(
588621
{

types/firestore.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,13 @@ declare namespace FirebaseFirestore {
227227
*/
228228
projectId?: string;
229229

230+
/**
231+
* The database name. If omitted, the default database will be used.
232+
*
233+
* @internal
234+
*/
235+
databaseId?: string;
236+
230237
/** The hostname to connect to. */
231238
host?: string;
232239

0 commit comments

Comments
 (0)