Skip to content

fix(auth): capture FIREBASE_AUTH_EMULATOR_HOST at init time#3080

Open
daytonmux wants to merge 2 commits intofirebase:mainfrom
daytonmux:daytonmux/auth-emulator-per-app
Open

fix(auth): capture FIREBASE_AUTH_EMULATOR_HOST at init time#3080
daytonmux wants to merge 2 commits intofirebase:mainfrom
daytonmux:daytonmux/auth-emulator-per-app

Conversation

@daytonmux
Copy link

Summary

Fixes #2948.

FIREBASE_AUTH_EMULATOR_HOST was read from process.env on every API call, which meant it affected all initialized apps globally. This made it impossible to have one app pointing to the emulator and another to the cloud project in the same process — unlike Firestore, Database, and Storage which already capture their emulator env vars at init time.

This change captures the value of FIREBASE_AUTH_EMULATOR_HOST once when the Auth service is initialized and stores it per-instance, so each app remembers its own emulator configuration independently.

What changed

  • auth-api-request.ts: AuthResourceUrlBuilder, TenantAwareAuthResourceUrlBuilder, and AuthHttpClient now receive the emulator host/flag as constructor parameters instead of reading from process.env. AbstractAuthRequestHandler captures emulatorHost() once at construction and threads it through to all URL builders and the HTTP client. TenantAwareAuthRequestHandler accepts an optional emulator host override so lazily-created tenant handlers inherit the frozen value.
  • base-auth.ts: BaseAuth derives its emulatorMode from the request handler captured value instead of calling useEmulator() on every verifyIdToken/verifySessionCookie/_verifyAuthBlockingToken call. createFirebaseTokenGenerator accepts an optional isEmulator override for the same reason.
  • tenant-manager.ts: TenantManager captures the emulator host at construction and passes it to TenantAwareAuth instances created lazily by authForTenant(), so tenant auth inherits the original emulator state.

Test plan

  • All 6197 existing unit tests pass (npm test)
  • Lint passes
  • New tests in auth-api-request.spec.ts:
    • Emulator mode persists after env var is deleted post-init
    • Non-emulator mode persists when env var is set after init
  • New tests in auth.spec.ts:
    • verifyIdToken() retains emulator behavior after env var deletion
    • verifySessionCookie() retains emulator behavior after env var deletion
    • authForTenant() does not use emulator when env var set after Auth init
    • authForTenant() uses emulator when env var set before Auth init (and deleted after)

- Updated constructors in `AuthResourceUrlBuilder`, `TenantAwareAuthResourceUrlBuilder`, `AuthHttpClient`, and `AbstractAuthRequestHandler` to accept an optional emulator host parameter.
- Modified token generation and verification methods in `BaseAuth` to utilize the emulator mode based on the new parameter.
- Added tests to ensure correct behavior of emulator settings, including persistence after environment variable changes.
- Improved handling of emulator state in `TenantManager` and `TenantAwareAuth` classes.
@google-cla
Copy link

google-cla bot commented Feb 25, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @daytonmux, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses an issue where the FIREBASE_AUTH_EMULATOR_HOST environment variable was read on every API call, leading to inconsistent emulator behavior across multiple Firebase Auth app instances within the same process. The core change involves refactoring the Auth service to capture the emulator host configuration at initialization, ensuring that each Auth instance maintains its own independent emulator state. This brings Auth's emulator handling in line with other Firebase services like Firestore, Database, and Storage, which already capture their emulator environment variables at init time, thereby enabling more robust and predictable multi-app setups.

Highlights

  • Emulator Host Capture: The FIREBASE_AUTH_EMULATOR_HOST environment variable is now captured once at the Auth service initialization time and stored per-instance, ensuring consistent emulator configuration for each app.
  • Dependency Injection for Emulator State: The emulator host/flag is now passed as constructor parameters to AuthResourceUrlBuilder, TenantAwareAuthResourceUrlBuilder, and AuthHttpClient, rather than being read dynamically from process.env on every API call.
  • Consistent Emulator Mode in BaseAuth: The BaseAuth class now derives and stores its emulatorMode from the request handler's captured value, ensuring verifyIdToken, verifySessionCookie, and _verifyAuthBlockingToken consistently use the initial emulator state.
  • Tenant-Aware Emulator Configuration: The TenantManager captures the emulator host at construction and passes it to TenantAwareAuth instances, allowing lazily-created tenant handlers to inherit the correct emulator configuration.
  • New Unit Tests: Added new unit tests to auth-api-request.spec.ts and auth.spec.ts to validate the persistence and isolation of emulator mode across different initialization scenarios and tenant configurations.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • src/auth/auth-api-request.ts
    • Modified AuthResourceUrlBuilder and TenantAwareAuthResourceUrlBuilder constructors to accept an optional emHost parameter for emulator host configuration.
    • Updated AuthHttpClient to store an isEmulator flag passed during construction, which is then used in its getToken method.
    • Introduced emulatorHostValue property in AbstractAuthRequestHandler and updated its constructor to capture the emulator host, passing it to the AuthHttpClient.
    • Adjusted AuthRequestHandler and TenantAwareAuthRequestHandler to pass the captured emulatorHostValue to their respective URL builders.
  • src/auth/base-auth.ts
    • Updated createFirebaseTokenGenerator to accept an optional isEmulator parameter, allowing explicit control over emulator mode for token generation.
    • Added a emulatorMode property to the BaseAuth class, initialized from the authRequestHandler's captured emulator host value.
    • Modified verifyIdToken, verifySessionCookie, and _verifyAuthBlockingToken methods to use the stored emulatorMode property instead of dynamically checking the environment variable.
  • src/auth/tenant-manager.ts
    • Updated the TenantAwareAuth constructor to accept an optional emHost parameter, which is then passed to its super constructor and createFirebaseTokenGenerator.
    • Added an emulatorHost property to the TenantManager class, capturing the emulator host from its authRequestHandler during construction.
    • Modified the authForTenant method to pass the captured emulatorHost to newly created TenantAwareAuth instances.
  • test/unit/auth/auth-api-request.spec.ts
    • Added a test case to verify that emulator mode persists even after the FIREBASE_AUTH_EMULATOR_HOST environment variable is deleted post-initialization.
    • Added a test case to confirm that non-emulator mode persists when the FIREBASE_AUTH_EMULATOR_HOST environment variable is set after initialization.
  • test/unit/auth/auth.spec.ts
    • Introduced new test cases to ensure authForTenant() correctly isolates emulator behavior, verifying that tenant auth instances inherit the emulator state from their parent Auth instance at creation time.
    • Added tests to confirm that verifyIdToken() and verifySessionCookie() retain their emulator behavior even if the FIREBASE_AUTH_EMULATOR_HOST environment variable is deleted after Auth initialization.
Activity
  • All 6197 existing unit tests passed.
  • Lint checks passed.
  • New unit tests were added to auth-api-request.spec.ts to cover emulator host persistence scenarios.
  • New unit tests were added to auth.spec.ts to cover authForTenant() emulator isolation and verifyIdToken()/verifySessionCookie() behavior after environment variable changes.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the handling of the FIREBASE_AUTH_EMULATOR_HOST environment variable to capture its value at initialization time for each Auth instance, making the emulator configuration instance-specific rather than global. The changes are consistently applied across auth-api-request.ts, base-auth.ts, and tenant-manager.ts to ensure the emulator state is correctly managed and propagated, including for lazily-created tenant-aware auth instances. The new tests in auth-api-request.spec.ts and auth.spec.ts effectively validate this new behavior. The implementation appears correct and complete.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FIREBASE_AUTH_EMULATOR_HOST affects all initailized apps, unlike other emulator env var

2 participants