From firebase-development
Guides TDD workflow for adding features to existing Firebase projects: Cloud Functions, Firestore collections, API endpoints, security rules, emulator verification.
npx claudepluginhub 2389-research/claude-plugins --plugin firebase-developmentThis skill uses the workspace's default tool permissions.
This sub-skill guides adding new features to existing Firebase projects using TDD. It handles Cloud Functions, Firestore collections, and API endpoints.
Generates design tokens/docs from CSS/Tailwind/styled-components codebases, audits visual consistency across 10 dimensions, detects AI slop in UI.
Records polished WebM UI demo videos of web apps using Playwright with cursor overlay, natural pacing, and three-phase scripting. Activates for demo, walkthrough, screen recording, or tutorial requests.
Delivers idiomatic Kotlin patterns for null safety, immutability, sealed classes, coroutines, Flows, extensions, DSL builders, and Gradle DSL. Use when writing, reviewing, refactoring, or designing Kotlin code.
This sub-skill guides adding new features to existing Firebase projects using TDD. It handles Cloud Functions, Firestore collections, and API endpoints.
Key principles:
{success, message, data?} response patternDo not use for:
firebase-development:project-setupfirebase-development:debugfirebase-development:validateCreate checklist with these 12 steps:
Determine what's being added:
Examine the project to understand patterns:
ls -la functions/src/
grep -r "onRequest" functions/src/
grep "express" functions/package.json
Determine: Architecture style, auth method, security model.
Reference: docs/examples/express-function-architecture.md
Create test file before implementation:
// ABOUTME: Unit tests for [feature name] functionality
// ABOUTME: Tests [what the feature does] with various scenarios
import { describe, it, expect } from 'vitest';
import { handleYourFeature } from '../../tools/yourFeature';
describe('handleYourFeature', () => {
it('should return success when given valid input', async () => {
const result = await handleYourFeature('user-123', { name: 'test' });
expect(result.success).toBe(true);
});
it('should return error for invalid input', async () => {
const result = await handleYourFeature('user-123', { name: '' });
expect(result.success).toBe(false);
});
});
Run test to confirm it fails: npm run test
Create implementation file:
// ABOUTME: Implements [feature name] for [purpose]
// ABOUTME: Returns {success, message, data?} response
export async function handleYourFeature(
userId: string,
params: { name: string }
): Promise<{ success: boolean; message: string; data?: any }> {
if (!userId) {
return { success: false, message: 'Authentication required' };
}
if (!params.name) {
return { success: false, message: 'Invalid input: name required' };
}
// Implementation here
return { success: true, message: 'Success', data: { /* ... */ } };
}
Reference: docs/examples/express-function-architecture.md
Update firestore.rules for new collections:
Server-write-only (preferred):
match /yourCollection/{docId} {
allow read: if request.auth != null;
allow write: if false; // Only Cloud Functions
}
Client-write (if needed):
match /yourCollection/{docId} {
allow create: if request.auth != null &&
request.resource.data.userId == request.auth.uid;
allow update: if request.auth != null &&
resource.data.userId == request.auth.uid &&
request.resource.data.diff(resource.data).affectedKeys()
.hasOnly(['name', 'updatedAt']);
}
Reference: docs/examples/firestore-rules-patterns.md
Add to firestore.indexes.json for complex queries:
{
"collectionGroup": "yourCollection",
"fields": [
{"fieldPath": "userId", "order": "ASCENDING"},
{"fieldPath": "createdAt", "order": "DESCENDING"}
]
}
Skip if no complex queries (single-field indexes are automatic).
Based on project pattern:
API Keys:
app.post('/endpoint', apiKeyGuard, async (req, res) => {
const userId = req.userId!;
// ...
});
Firebase Auth:
if (!req.auth) {
res.status(401).json({ success: false, message: 'Auth required' });
return;
}
const userId = req.auth.uid;
Reference: docs/examples/api-key-authentication.md
All handlers use consistent pattern:
interface HandlerResponse {
success: boolean;
message: string;
data?: any;
}
Include validation at every layer (defense in depth).
Add to functions/src/index.ts:
Express: Add route or switch case
Domain-grouped: export * from './yourDomain';
Individual: Import and export in index.js
Verify: npm run build
Run tests: npm run test
All tests should pass. If not, fix implementation (not tests).
Create functions/src/__tests__/emulator/yourFeature.test.ts:
Test complete workflow with emulators:
Run: npm run test:emulator (with emulators running)
firebase emulators:start
open http://127.0.0.1:4000
Verify:
All handlers MUST return:
// Success
{ success: true, message: "Created", data: { id: "abc" } }
// Error
{ success: false, message: "Invalid input" }
Before marking complete:
docs/examples/express-function-architecture.mddocs/examples/api-key-authentication.mddocs/examples/firestore-rules-patterns.mddocs/examples/emulator-workflow.md