← all adapters
firebase-style
simulates Firebase Auth + Firestore + Cloud Messaging API v1
restadapter v0.1.022 routes
verification
use it
# add to stunt.yaml
services:
firebase:
adapter: embedded:firebase-style
# then
$ stunt upThe embedded: source extracts this adapter from the binary — no git clone, fully offline.
how to mock the Firebase Auth + Firestore + Cloud Messaging API locally
Install stunt, paste the service block above into stunt.yaml, run stunt up — then point your client at localhost instead of Firebase Auth + Firestore + Cloud Messaging API. It works offline, keeps state across requests and restarts, and every response is synthetic: the route shapes, status codes, pagination, and webhook delivery follow the real Firebase Auth + Firestore + Cloud Messaging API v1 surface — the data is fake, the behavior is real.
backing stores
usersdocumentsmessages
api surface (22)
generated from the adapter manifest — exactly what boots, nothing more
22 routes
POST/v1/accounts:signInWithPassword
POST/v1/accounts:signUp
POST/v1/accounts:signInWithIdp
POST/v1/accounts:getAccountInfo
POST/v1/accounts:lookup
POST/identitytoolkit/v3/relyingparty/{action}
POST/v1/token
POST/v1/projects/{project}/databases/(default)/documents:runQuery
GET/v1/projects/{project}/databases/(default)/documents/{collection}
POST/v1/projects/{project}/databases/(default)/documents/{collection}
GET/v1/projects/{project}/databases/(default)/documents/{collection}/{id}
PATCH/v1/projects/{project}/databases/(default)/documents/{collection}/{id}
DELETE/v1/projects/{project}/databases/(default)/documents/{collection}/{id}
GET/v1/projects/{project}/databases/(default)/documents/{collection}/{document}/{sub}
POST/v1/projects/{project}/databases/(default)/documents/{collection}/{document}/{sub}
GET/v1/projects/{project}/databases/(default)/documents/{collection}/{document}/{sub}/{id}
PATCH/v1/projects/{project}/databases/(default)/documents/{collection}/{document}/{sub}/{id}
DELETE/v1/projects/{project}/databases/(default)/documents/{collection}/{document}/{sub}/{id}
POST/v1/projects/{project}/messages:send
GET/v1/projects/{project}/messages
POST/v1/projects/{project}/topics/{topic}:subscribe
POST/v1/projects/{project}/topics/{topic}:unsubscribe
VM-verified behaviors (28)
- ✓signUp mints the Identity Toolkit token set with a padded localId
- ✓duplicate and email-less signUps are Firebase-coded 400s
- ✓password sign-in round-trips the user; bad credentials answer the real codes
- ✓signInWithIdp provisions a verified Google user
- ✓the v3 relyingparty dispatcher mirrors verifyPassword and 404s unknown actions
- ✓endpoints accept Bearer or key and reject anonymous requests 401
- ✓getAccountInfo resolves each idToken to the user it was minted for
- ✓unknown and empty idTokens are 401 INVALID_ID_TOKEN
- ✓the idToken dies at 1h while its refresh token survives
- ✓v3 refreshToken rotates the token pair for the bound user
- ✓unknown and missing refresh tokens are 400 INVALID_REFRESH_TOKEN
- ✓POST /v1/token exchanges a refresh token in the securetoken shape
- ✓the grant rejects wrong grant types and unknown tokens
- ✓create wraps fields in Firestore typed values under a full resource name
- ✓get reads the document back; unknown ids are 404 NOT_FOUND
- ✓PATCH merges fields, bumps updateTime, and upserts unknown ids
- ✓explicit documentIds are scoped per project+collection and 409 on reuse
- ✓delete returns an empty 200 and leaves 404s behind (its own project only)
- ✓list pages with pageSize/pageToken and rejects a malformed token
- ✓subcollections nest under their parent document path
- ✓runQuery filters, sorts, and limits over typed fields
- ✓IN and ARRAY_CONTAINS resolve over array values
- ✓queries are project-scoped and malformed bodies are 400 INVALID_ARGUMENT
- ✓a token send is stored with its recipient and answers with its resource name
- ✓a send must carry exactly one target
- ✓topic and condition sends fan out to the subscribed tokens
- ✓unsubscribing shrinks the fanout and a bare subscribe is a 400
- ✓the stored message list is project-scoped
Not implemented (4)
- No Realtime Database, Cloud Storage, or App Check surfaces
- No password reset (sendOobCode), account update/delete, or phone auth
- No Firestore index management, listCollectionIds, batchGet, or listen
- runQuery lacks composite/unary filters, offset, and startAt/endAt cursors
Differs from the real API (8)
- Firestore subcollections supported one level deep only
- runQuery covers a structuredQuery subset: from/where/orderBy/limit, 8 filter ops
- Auth checks credential presence only; Bearer or key value never validated
- FCM topic :subscribe/:unsubscribe stand in for the Instance ID API
- GET .../messages lists sent messages — simulator extension, no real endpoint
- securetoken /v1/token errors use the Identity Toolkit envelope; real securetoken answers OAuth-style {error: invalid_grant}
- securetoken access_token mirrors id_token; real Firebase mints distinct tokens
- signUp includes registered:true and an empty displayName (real API emits those on sign-in only)
want more of the Firebase Auth + Firestore + Cloud Messaging API surface? adapters are YAML + Starlark — the authoring guide covers adding routes, fixtures, and state machines. Open an issue for anything big first, or just file a PR — merged routes ship in the next release.