Skip to content
Latchkey

Firebase "Failed to authenticate, have you run firebase login?" in CI

The Firebase CLI found no credentials on the runner. firebase login is interactive and stores a token in your home directory, which a fresh CI runner does not have. In CI you authenticate non-interactively with a service account.

What this error means

A firebase deploy or other command fails immediately with "Error: Failed to authenticate, have you run firebase login?" on a runner that never ran an interactive login.

firebase
Error: Failed to authenticate, have you run firebase login?

Common causes

No stored login on a fresh runner

Interactive firebase login writes a token under ~/.config/configstore/firebase-tools.json. A clean CI runner has no such file, so the CLI has nothing to authenticate with.

Relying on interactive auth in a non-interactive job

CI cannot open a browser to complete the OAuth flow, so any command that assumes an interactive login fails at the auth step.

How to fix it

Authenticate with a service account

  1. Create a service account in the Google Cloud console and download its JSON key.
  2. Store the key as a CI secret and write it to a file on the runner.
  3. Point GOOGLE_APPLICATION_CREDENTIALS at that file so the CLI uses it.
.github/workflows/ci.yml
env:
  GOOGLE_APPLICATION_CREDENTIALS: ${{ github.workspace }}/gcp-key.json
run: |
  echo '${{ secrets.FIREBASE_SERVICE_ACCOUNT }}' > "$GOOGLE_APPLICATION_CREDENTIALS"
  firebase deploy --project my-project --non-interactive

Use the official deploy action

The FirebaseExtended/action-hosting-deploy action reads a service account secret and authenticates the CLI for you.

.github/workflows/ci.yml
- uses: FirebaseExtended/action-hosting-deploy@v0
  with:
    repoToken: ${{ secrets.GITHUB_TOKEN }}
    firebaseServiceAccount: ${{ secrets.FIREBASE_SERVICE_ACCOUNT }}
    projectId: my-project

How to prevent it

  • Never rely on interactive firebase login in CI; use a service account.
  • Keep the service account JSON in a CI secret, not in the repo.
  • Pass --non-interactive so the CLI fails loudly instead of prompting.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →