diff --git a/.changeset/fresh-experts-mix.md b/.changeset/fresh-experts-mix.md new file mode 100644 index 00000000000..00a6bb1c16d --- /dev/null +++ b/.changeset/fresh-experts-mix.md @@ -0,0 +1,6 @@ +--- +"@firebase/database-compat": patch +"@firebase/database": patch +--- + +Fixed issue where hostname set by `connectDatabaseEmulator` was being overridden by longpolling response diff --git a/packages/database-compat/test/database.test.ts b/packages/database-compat/test/database.test.ts index e72d7e53c34..8e984e211a6 100644 --- a/packages/database-compat/test/database.test.ts +++ b/packages/database-compat/test/database.test.ts @@ -272,6 +272,7 @@ describe('Database Tests', () => { }); it('refFromURL() validates argument', () => { + // TODO: Remove all any references const db = (firebase as any).database(); expect(() => { const ref = (db as any).refFromURL(); @@ -279,11 +280,18 @@ describe('Database Tests', () => { }); it('can call useEmulator before use', () => { - const db = (firebase as any).database(); + const db = firebase.database(); db.useEmulator('localhost', 1234); + // Cast as any as _delegate isn't a public property + expect((db as any)._delegate._repo.repoInfo_.isUsingEmulator).to.be.true; expect(db.ref().toString()).to.equal('http://localhost:1234/'); }); + it('initializes usingEmulator to false before use', () => { + const db = firebase.database(); + expect((db as any)._delegate._repo.repoInfo_.isUsingEmulator).to.be.false; + }); + it('cannot call useEmulator after use', () => { const db = (firebase as any).database(); diff --git a/packages/database/src/api/Database.ts b/packages/database/src/api/Database.ts index f1a27492442..6cf60d5fbd6 100644 --- a/packages/database/src/api/Database.ts +++ b/packages/database/src/api/Database.ts @@ -95,7 +95,8 @@ function repoManagerApplyEmulatorSettings( repo.repoInfo_.webSocketOnly, repo.repoInfo_.nodeAdmin, repo.repoInfo_.persistenceKey, - repo.repoInfo_.includeNamespaceInQueryParams + repo.repoInfo_.includeNamespaceInQueryParams, + /*isUsingEmulator=*/ true ); if (tokenProvider) { diff --git a/packages/database/src/core/RepoInfo.ts b/packages/database/src/core/RepoInfo.ts index de0e4603be1..9d4c1abe36b 100644 --- a/packages/database/src/core/RepoInfo.ts +++ b/packages/database/src/core/RepoInfo.ts @@ -45,7 +45,8 @@ export class RepoInfo { public readonly webSocketOnly: boolean, public readonly nodeAdmin: boolean = false, public readonly persistenceKey: string = '', - public readonly includeNamespaceInQueryParams: boolean = false + public readonly includeNamespaceInQueryParams: boolean = false, + public readonly isUsingEmulator: boolean = false ) { this._host = host.toLowerCase(); this._domain = this._host.substr(this._host.indexOf('.') + 1); diff --git a/packages/database/src/realtime/Connection.ts b/packages/database/src/realtime/Connection.ts index 430d68ec9b0..80fb9520fb1 100644 --- a/packages/database/src/realtime/Connection.ts +++ b/packages/database/src/realtime/Connection.ts @@ -337,14 +337,19 @@ export class Connection { if (MESSAGE_DATA in controlData) { const payload = controlData[MESSAGE_DATA]; if (cmd === SERVER_HELLO) { - this.onHandshake_( - payload as { + const handshakePayload = { + ...(payload as { ts: number; v: string; h: string; s: string; - } - ); + }) + }; + if (this.repoInfo_.isUsingEmulator) { + // Upon connecting, the emulator will pass the hostname that it's aware of, but we prefer the user's set hostname via `connectDatabaseEmulator` over what the emulator passes. + handshakePayload.h = this.repoInfo_.host; + } + this.onHandshake_(handshakePayload); } else if (cmd === END_TRANSMISSION) { this.log_('recvd end transmission on primary'); this.rx_ = this.secondaryConn_;