diff --git a/src/auth/credential.ts b/src/auth/credential.ts index 6428b2651a..e794bbc171 100644 --- a/src/auth/credential.ts +++ b/src/auth/credential.ts @@ -419,6 +419,15 @@ export class ApplicationDefaultCredential implements FirebaseCredential { } } +export class DatabaseEmulatorCredential implements Credential { + public getAccessToken(): Promise { + return Promise.resolve({ + expires_in: 1000, + access_token: 'owner', + }); + } +} + function credentialFromFile(filePath: string, httpAgent?: Agent): Credential { const credentialsFile = readCredentialFile(filePath); if (typeof credentialsFile !== 'object') { diff --git a/src/database/database.ts b/src/database/database.ts index 8ca2741f10..a4d2a9e6d8 100644 --- a/src/database/database.ts +++ b/src/database/database.ts @@ -1,3 +1,4 @@ +import {DatabaseEmulatorCredential} from '../auth/credential'; import {FirebaseApp} from '../firebase-app'; import {FirebaseDatabaseError} from '../utils/error'; import {FirebaseServiceInterface, FirebaseServiceInternalsInterface} from '../firebase-service'; @@ -5,6 +6,27 @@ import {Database} from '@firebase/database'; import * as validator from '../utils/validator'; +const APP_OPTIONS_PROJECT_ID = 'projectId'; +const APP_OPTIONS_CREDENTIAL = 'credential'; + +/** + * Constant holding the fully-qualified domain URI for a database emulator + * instance. If specified, the contents of this variable will be used to + * set `databaseURL` in FirebaseAppOptions. The varaible should be a complete + * URI specifying a transfer protocol, hostname, and port number: + * + * FIREBASE_DATABASE_EMULATOR_HOST=http://localhost:9000 + * + * + * If a `projectId` is specified in FirebaseAppOptions, the database url will + * include the `ns=${projectId}` query parameter to identify the appropriate + * namespace within the emulator. The final `databaseURL` for a firebase project + * called "test" would be: + * + * http://localhost:9000?ns=test + */ +const FIREBASE_DATABASE_EMULATOR_HOST_VAR = 'FIREBASE_DATABASE_EMULATOR_HOST'; +const DEFAULT_DATABASE_EMULATOR_PROJECT_ID = 'fake-server'; /** * Internals of a Database instance. @@ -55,6 +77,12 @@ export class DatabaseService implements FirebaseServiceInterface { } public getDatabase(url?: string): Database { + const emulatorUrl = process.env[FIREBASE_DATABASE_EMULATOR_HOST_VAR]; + if (emulatorUrl) { + url = `${emulatorUrl}?ns=${this.appInternal.options[APP_OPTIONS_PROJECT_ID] || + DEFAULT_DATABASE_EMULATOR_PROJECT_ID }`; + this.appInternal.options[APP_OPTIONS_CREDENTIAL] = new DatabaseEmulatorCredential(); + } const dbUrl: string = this.ensureUrl(url); if (!validator.isNonEmptyString(dbUrl)) { throw new FirebaseDatabaseError({