Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add internal multi-db support #1761

Merged
merged 2 commits into from Sep 30, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 27 additions & 1 deletion dev/src/index.ts
Expand Up @@ -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.
*
Expand Down Expand Up @@ -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(
Expand All @@ -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
Expand Down Expand Up @@ -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.
Expand All @@ -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}`;
}

/**
Expand Down
41 changes: 37 additions & 4 deletions dev/test/index.ts
Expand Up @@ -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 */
});
Expand Down Expand Up @@ -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];

Expand Down Expand Up @@ -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'
);
});

Expand All @@ -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(),
});
Expand All @@ -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(
{
Expand Down
7 changes: 7 additions & 0 deletions types/firestore.d.ts
Expand Up @@ -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;

Expand Down