diff --git a/packages/database/src/api/Database.ts b/packages/database/src/api/Database.ts index 72ae85c08a1..29ea7a433b1 100644 --- a/packages/database/src/api/Database.ts +++ b/packages/database/src/api/Database.ts @@ -27,6 +27,7 @@ import { Provider } from '@firebase/component'; import { getModularInstance, createMockUserToken, + // deepEqual, EmulatorMockTokenOptions, getDefaultEmulatorHostnameAndPort } from '@firebase/util'; @@ -38,7 +39,7 @@ import { FirebaseAuthTokenProvider } from '../core/AuthTokenProvider'; import { Repo, repoInterrupt, repoResume, repoStart } from '../core/Repo'; -import { RepoInfo } from '../core/RepoInfo'; +import { RepoInfo, RepoInfoEmulatorOptions} from '../core/RepoInfo'; import { parseRepoInfo } from '../core/util/libs/parser'; import { newEmptyPath, pathIsEmpty } from '../core/util/Path'; import { @@ -84,19 +85,20 @@ let useRestClient = false; */ function repoManagerApplyEmulatorSettings( repo: Repo, - host: string, - port: number, - tokenProvider?: AuthTokenProvider + hostAndPort: string, + emulatorOptions: RepoInfoEmulatorOptions, + tokenProvider?: AuthTokenProvider, ): void { repo.repoInfo_ = new RepoInfo( - `${host}:${port}`, + hostAndPort, /* secure= */ false, repo.repoInfo_.namespace, repo.repoInfo_.webSocketOnly, repo.repoInfo_.nodeAdmin, repo.repoInfo_.persistenceKey, repo.repoInfo_.includeNamespaceInQueryParams, - /*isUsingEmulator=*/ true + /*isUsingEmulator=*/ true, + emulatorOptions ); if (tokenProvider) { @@ -350,13 +352,23 @@ export function connectDatabaseEmulator( ): void { db = getModularInstance(db); db._checkNotDeleted('useEmulator'); + const hostAndPort = `${host}:${port}`; + const repo = db._repoInternal; if (db._instanceStarted) { + // If the instance has already been started, then silenty fail if this function is called again + // with the same parameters. If the parameters differ then assert. + if ( + true + // hostAndPort === db._repoInternal.repoInfo_.host //&& + //deepEqual(options, repo.repoInfo_.emulatorOptions) + ) { + return; + } fatal( - 'Cannot call useEmulator() after instance has already been initialized.' + 'connectDatabaseEmulator() cannot alter the emulator configuration after the database instance has started.' ); } - const repo = db._repoInternal; let tokenProvider: EmulatorTokenProvider | undefined = undefined; if (repo.repoInfo_.nodeAdmin) { if (options.mockUserToken) { @@ -374,7 +386,7 @@ export function connectDatabaseEmulator( } // Modify the repo to apply emulator settings - repoManagerApplyEmulatorSettings(repo, host, port, tokenProvider); + repoManagerApplyEmulatorSettings(repo, hostAndPort, options, tokenProvider); } /** diff --git a/packages/database/src/core/RepoInfo.ts b/packages/database/src/core/RepoInfo.ts index 025b746b951..2f2fd61ae30 100644 --- a/packages/database/src/core/RepoInfo.ts +++ b/packages/database/src/core/RepoInfo.ts @@ -22,15 +22,16 @@ import { LONG_POLLING, WEBSOCKET } from '../realtime/Constants'; import { PersistentStorage } from './storage/storage'; import { each } from './util/util'; +export interface RepoInfoEmulatorOptions { + mockUserToken?: string | EmulatorMockTokenOptions; +}; + /** * A class that holds metadata about a Repo object */ export class RepoInfo { private _host: string; private _domain: string; - private _emulatorOptions: { - mockUserToken?: EmulatorMockTokenOptions | string; - }; internalHost: string; /** @@ -49,11 +50,11 @@ export class RepoInfo { public readonly nodeAdmin: boolean = false, public readonly persistenceKey: string = '', public readonly includeNamespaceInQueryParams: boolean = false, - public readonly isUsingEmulator: boolean = false + public readonly isUsingEmulator: boolean = false, + public readonly emulatorOptions: RepoInfoEmulatorOptions | null = null ) { this._host = host.toLowerCase(); this._domain = this._host.substr(this._host.indexOf('.') + 1); - this._emulatorOptions = {}; this.internalHost = (PersistentStorage.get('host:' + host) as string) || this._host; } @@ -82,12 +83,6 @@ export class RepoInfo { } } - get emulatorOptions(): { - mockUserToken?: EmulatorMockTokenOptions | string; - } { - return this._emulatorOptions; - } - toString(): string { let str = this.toURLString(); if (this.persistenceKey) {