A reference Expo + Firebase project showing what an AI agent produces when it follows the DentVega/firebase-agent-skills package — including the SOLID layering prescribed by firebase-architecture.
This repo is meant to be browsed, not run as-is. It has no GoogleService-Info.plist / google-services.json, no eas.json, and the Firebase project ID is a placeholder.
npx create-expo-app@latest firebase-skills-example --template blank-typescript
npx skills add DentVega/firebase-agent-skillsThen this prompt:
Integrate Firebase Authentication (email/password + Google Sign-In) and Cloud Firestore in this Expo app. Use the Firebase skills installed in this repo. Apply the architecture skill — separate data access from UI so the writes are testable without an emulator. Add a sign-in screen, an auth-gated home screen, and a
todoscollection scoped to the signed-in user with security rules.
lib/
├── repositories/
│ ├── todos.ts ← TodosRepository interface (the contract)
│ ├── firestoreTodos.ts ← THE ONLY file importing @react-native-firebase/firestore
│ ├── inMemoryTodos.ts ← Test-mode implementation, ~50 lines, no network
│ └── context.tsx ← DIP wiring (provider + useTodosRepo hook)
├── hooks/
│ ├── useUid.ts ← narrow auth seam
│ ├── useTodos.ts ← read-side hook
│ └── useTodoActions.ts ← write-side hook (separated from reads — SRP)
app/
├── _layout.tsx ← auth-gated routing + mounts TodosRepoProvider
├── (auth)/sign-in.tsx ← email + Google sign-in
└── (app)/index.tsx ← presentation only — no Firestore imports
__tests__/
└── inMemoryTodos.test.ts ← contract tests, run in <1ms each, no emulator
| File / dir | Skill that produced it | What it shows |
|---|---|---|
| app.json | firebase-expo |
Config plugins, useFrameworks: "static" |
| package.json | firebase-expo, firebase-auth, firebase-firestore |
The exact dependency set the skills install |
| lib/repositories/todos.ts | firebase-architecture |
The TodosRepository interface — contract every implementation honors |
| lib/repositories/firestoreTodos.ts | firebase-architecture + firebase-firestore |
The Firestore-backed implementation. Only file in the app that imports Firestore |
| lib/repositories/inMemoryTodos.ts | firebase-architecture |
In-memory implementation for tests |
| lib/repositories/context.tsx | firebase-architecture |
DIP wiring via React context |
| lib/hooks/useTodos.ts | firebase-architecture |
Read hook — depends on the abstraction, not on Firebase |
| lib/hooks/useTodoActions.ts | firebase-architecture |
Write hook — separate from reads (SRP) |
| app/_layout.tsx | firebase-auth + firebase-architecture |
Auth-state routing, mounts the repo provider |
| app/(auth)/sign-in.tsx | firebase-auth |
Email + Google sign-in screen |
| app/(app)/index.tsx | firebase-firestore + firebase-architecture |
Presentation-only screen — no Firestore imports |
| firestore.rules | firebase-firestore |
Default-deny rules anchored to request.auth.uid |
| firebase.json | firebase-firestore, firebase-emulators |
Firestore config + emulator suite ports |
| functions/src/index.ts | firebase-cloud-functions |
A v2 callable function with the canonical auth check |
| __tests__/inMemoryTodos.test.ts | firebase-architecture |
Sub-millisecond contract tests with the in-memory repo |
Because the component depends on useTodos(uid) / useTodoActions(uid) — not on firestore() — the entire write flow is testable in microseconds:
const repo = createInMemoryTodos();
const id = await repo.add("alice", { title: "buy milk" });
await repo.toggle("alice", id, true);
// assertions...No emulator startup. No Firebase init. No network. Swap firestoreTodos for createInMemoryTodos() in a <TodosRepoProvider repo={...}> and the UI runs in any test environment.
- Replace placeholders — search for
your-project-id,com.yourcompany.yourapp, andYOUR_WEB_CLIENT_IDand fill in your own. - Add config files — download
GoogleService-Info.plistandgoogle-services.jsonfrom the Firebase Console and drop them at the repo root. - Build with EAS — Firebase native modules don't work in Expo Go. Follow
firebase-expo/SKILL.md's section 5. - Deploy rules and functions:
npx -y firebase-tools@latest deploy --only firestore:rules,functions
- DentVega/firebase-agent-skills — the skills package itself
- firebase/agent-skills — Firebase's official skills (web-first)
- agentskills.io — the underlying format spec
MIT