Firebase connector
Watch a Firebase project's App Hosting rollouts and builds so a failed deploy shows up as an Orgabot incident instead of waiting to be found in the Firebase console.
App Hosting deploys fail quietly. The rollout goes red in the Firebase console, and unless you happen to open that console you find out later, from something else breaking. The Firebase connector closes that gap: Orgabot polls the project you name and turns a failed App Hosting rollout or build into an ordinary incident on the dashboard, alongside failed missions and failed CI runs.
Connect a project
orgabot firebase connect --project <firebase-project-id> \
[--orka-project <project>] \
[--backend <location>/<backend>]… \
[--credentials <service-account.json>] \
[--poll-seconds N]
orgabot firebase status # what is connected, and the last reading
orgabot firebase check # take a reading right now
orgabot firebase disconnect--project is the only required flag. With no --backend, Orgabot discovers the project's App Hosting backends on each poll and watches all of them; naming backends explicitly narrows it (and avoids the fan-out cap on a project with many).
--orka-project maps the Firebase project to a registered Orgabot project - the repository App Hosting builds from. It is optional, and it decides one thing: whether a failed rollout is fixable. Firebase's API does not say which repository builds a backend, and Orgabot will not guess one, so an unmapped incident is still reported but its Fix with Orgabot button is disabled with that explanation. Map one and the button launches an ordinary fix mission on that repository.
Credentials
The connector needs a Google credential that can read App Hosting on the project. It looks in three places, in order:
--credentials <service-account.json>- the path recorded at connect time.GOOGLE_APPLICATION_CREDENTIALS- the Google-standard variable, usually already set on a machine that deploys.ORGABOT_FIREBASE_ACCESS_TOKEN- a short-lived token supplied out of band.
Only the path is stored, never the key. Orgabot signs a short-lived assertion with the service-account key at use time and exchanges it for an access token scoped to cloud-platform.read-only, which is the narrowest scope that can read rollouts. The key, the assertion, and the minted token are never logged, never persisted, and are scrubbed out of any error the connector raises.
The service account needs read access to App Hosting on the project (for example the Firebase App Hosting Viewer or Viewer role). Authentication is not authorization: a credential that signs in fine but lacks that grant produces a 403, and the dashboard says so rather than showing an empty, healthy-looking list.
What becomes an incident
Only a terminal failure:
| Observed state | Incident? |
|---|---|
Rollout FAILED | Yes |
Build FAILED with no failed rollout of its own | Yes |
Rollout SUCCEEDED | No |
Rollout QUEUED / BUILDING / DEPLOYING | No - it has not failed yet |
Rollout CANCELLED | No - that was an operator's decision |
A failed rollout and the failed build behind it read as one incident, not two, and the incident carries the build's error message (which is where the actual cause usually is) plus the branch and commit it built from.
Classic Firebase Hosting is deliberately not reported. A classic Hosting deploy is atomic: a failed one never creates a release, so there is no failure state to observe, and inventing one would be a confident guess rather than evidence.
Where it shows up
- Security → Incidents, in an "Observed from Firebase" column beside the Orgabot and GitHub columns. The source filter gains a Firebase option.
- The Overview problem feed, scoped to the mapped Orgabot project.
Acknowledging works exactly as it does for the other sources - same durable store, same per-incident and bulk controls - so "Mark ALL as acknowledged" covers Firebase incidents too, scoped to whichever source filter is active.
Polling, and what it never does
The connector polls on the dashboard's own timer at the cadence you set (--poll-seconds, default 300, floor 60). The rate window belongs to the connector, not the caller: the dashboard re-renders every few seconds and asks far more often than the connector actually polls. orgabot firebase check is the one caller that bypasses the window, because you asked for a reading explicitly.
Polling never happens as a side effect of loading the dashboard page. GET /api/state sits outside the dashboard's request guards, so nothing reachable from it is allowed to spend your Google credential.
The connector is read-only. It calls only list methods and holds only a read-only scope: it never deploys, rolls back, re-runs a rollout, or changes a backend. Those are governed actions, and a fix mission launched from an incident is told so explicitly - it fixes the cause in the repository and leaves deploying to you.
When a poll cannot complete
An unreadable source is not evidence that nothing is failing, so a failed or partial poll does not clear the list. The connector keeps the previous reading, marks the source with what went wrong, and says so on the Incidents view. "I do not know" and "nothing is failing" are different answers, and the connector never confuses them.
If a project has more backends than one pass reads, the pass says which coverage it dropped rather than presenting a capped sweep as a complete one; name the backends you care about with --backend to avoid it.