Skip to content

feat: support two-phase non-interactive firebase login#10777

Open
joehan wants to merge 3 commits into
mainfrom
jh--no-localhost
Open

feat: support two-phase non-interactive firebase login#10777
joehan wants to merge 3 commits into
mainfrom
jh--no-localhost

Conversation

@joehan

@joehan joehan commented Jul 8, 2026

Copy link
Copy Markdown
Member

Description

Allows headless tools and AI agents to log the Firebase CLI into Google/Firebase in non-interactive environments using a two-phase login flow.

  • Initiating firebase login --non-interactive generates a PKCE codeVerifier and sessionId, writes it to the local configstore, and outputs a login URL with a verification code instructions.
  • Exchanging the code via firebase login <auth_code> retrieves the stored PKCE state, performs the remote token exchange, and records the active user session.

Before and After Command Outputs

Before

Running firebase login --non-interactive threw an error immediately:

Cannot run login in non-interactive mode. See login:ci to generate a token for use in non-interactive environments.

After

  1. Initiating the login:
$ firebase login --non-interactive

To sign in to the Firebase CLI:

1. Take note of your session ID:

   97548

2. Visit the URL below on any device and follow the instructions to get your code:

   https://auth.firebase.tools/login?code_challenge=MgMej1pXyJBOCEl4o5VQ1zPAEF4JRgW6WCNHnH1lBfA&session=97548b2c-fe34-4813-9d9d-93827425952a&attest=lWAgfQyI5wQ491SwVqsd8JCGXKWgKacAab60RXJMSqQ

3. Complete the login by running:

   firebase login <authorizationCode>
  1. Completing the login with the authorization code:
$ firebase login 4/0AdkVLPyTQOoo2mMMCsGpTl9ks_ozOmRGapvrd24bFQHaBmZ376AmaRNYx4nTs-HzU4Jnug
✔  Success! Logged in as joehanley@google.com

Scenarios Tested

  • Initiating the login flow in non-interactive mode.
  • Exchanging code with correct/matching state successfully.
  • Exchanging code when no login state is present or state fails verification.
  • Verified that full project listing commands (projects:list) works successfully post-authentication.

Sample Commands

firebase login --non-interactive
firebase login <authCode>

### Description
Allows headless tools and AI agents to log the Firebase CLI into Google/Firebase in non-interactive environments using a two-phase login flow.
- Initiating `firebase login --non-interactive` generates a PKCE `codeVerifier` and `sessionId`, writes it to the local `configstore`, and outputs a login URL with a verification code instructions.
- Exchanging the code via `firebase login <auth_code>` retrieves the stored PKCE state, performs the remote token exchange, and records the active user session.

### Before and After Command Outputs
#### Before
Running `firebase login --non-interactive` threw an error immediately:
```
Cannot run login in non-interactive mode. See login:ci to generate a token for use in non-interactive environments.
```

#### After
1. Initiating the login:
```
$ firebase login --non-interactive

To sign in to the Firebase CLI:

1. Take note of your session ID:

   97548

2. Visit the URL below on any device and follow the instructions to get your code:

   https://auth.firebase.tools/login?code_challenge=MgMej1pXyJBOCEl4o5VQ1zPAEF4JRgW6WCNHnH1lBfA&session=97548b2c-fe34-4813-9d9d-93827425952a&attest=lWAgfQyI5wQ491SwVqsd8JCGXKWgKacAab60RXJMSqQ

3. Complete the login by running:

   firebase login <authorizationCode>
```

2. Completing the login with the authorization code:
```
$ firebase login 4/0AdkVLPyTQOoo2mMMCsGpTl9ks_ozOmRGapvrd24bFQHaBmZ376AmaRNYx4nTs-HzU4Jnug
✔  Success! Logged in as joehanley@google.com
```

### Scenarios Tested
- Initiating the login flow in non-interactive mode.
- Exchanging code with correct/matching state successfully.
- Exchanging code when no login state is present or state fails verification.
- Verified that full project listing commands (`projects:list`) works successfully post-authentication.

### Sample Commands
`firebase login --non-interactive`
`firebase login <authCode>`

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

Copy link
Copy Markdown
Contributor

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 introduces support for a two-phase non-interactive authentication flow to firebase login using login [auth_code], allowing headless tools and agents to log in. It refactors the remote login logic in src/auth.ts into start and complete phases, updates the login command in src/commands/login.ts to handle these phases, and adds corresponding unit tests in src/commands/login.spec.ts. Feedback on the changes highlights a potential crash when accessing result.user.email without a truthiness check, and multiple violations of the repository style guide regarding the use of any as an escape hatch in error catch blocks and test assertions.

Comment thread src/commands/login.ts Outdated
Comment thread src/commands/login.ts
Comment on lines +58 to +61
} catch (e: any) {
configstore.delete("tempLoginState");
throw new FirebaseError(`Login failed: ${e.message}`, { exit: 1 });
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Using any as an escape hatch in the catch block violates the repository style guide. We should catch the error as unknown and safely extract the message.

      } catch (e: unknown) {
        configstore.delete("tempLoginState");
        const message = e instanceof Error ? e.message : String(e);
        throw new FirebaseError("Login failed: " + message, { exit: 1 });
      }
References
  1. Never use any or unknown as an escape hatch. Define proper interfaces/types or use type guards. (link)

Comment thread src/commands/login.ts
Comment thread src/commands/login.spec.ts Outdated
@joehan
joehan requested a review from richieforeman July 8, 2026 17:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants