50 lines
1.9 KiB
Cheetah
50 lines
1.9 KiB
Cheetah
---
|
|
description: "Firebase conventions for {{PROJECT_NAME}}"
|
|
alwaysApply: true
|
|
---
|
|
|
|
# Firebase Standards — {{PROJECT_NAME}}
|
|
|
|
## Firestore
|
|
- Collection names: `camelCase` plural — `users`, `products`, `orderItems`
|
|
- Document IDs: use Firebase auto-IDs unless a natural key exists
|
|
- **Streams vs Futures**: use `snapshots()` for live data, `get()` for one-time reads
|
|
- Always handle `FirebaseException` explicitly — catch by `e.code` not generic `Exception`
|
|
- Paginate large collections with `startAfterDocument` — never fetch unbounded collections
|
|
|
|
```dart
|
|
// ✅ Stream-based real-time listener
|
|
Stream<List<Product>> watchProducts() {
|
|
return _firestore.collection('products')
|
|
.where('isActive', isEqualTo: true)
|
|
.snapshots()
|
|
.map((snap) => snap.docs.map(Product.fromDoc).toList());
|
|
}
|
|
|
|
// ✅ Handle FirebaseException by code
|
|
try {
|
|
await _firestore.collection('orders').add(order.toMap());
|
|
} on FirebaseException catch (e) {
|
|
switch (e.code) {
|
|
case 'permission-denied': throw AppError.authError('Insufficient permissions');
|
|
case 'unavailable': throw AppError.networkError();
|
|
default: throw AppError.unknown(e);
|
|
}
|
|
}
|
|
```
|
|
|
|
## Firebase Auth
|
|
- Always use `authStateChanges()` stream — never cache auth state locally
|
|
- Handle all error codes: `user-not-found`, `wrong-password`, `email-already-in-use`, `network-request-failed`
|
|
- Sign-out: clear all local state AND call `FirebaseAuth.instance.signOut()`
|
|
|
|
## Cloud Functions
|
|
- Call via `FirebaseFunctions.instance.httpsCallable('functionName')`
|
|
- Handle `FirebaseFunctionsException` with `.code` and `.message`
|
|
- Never expose internal errors to client — functions return structured error responses
|
|
|
|
## Security (complement to security-standards.mdc)
|
|
- Firestore Security Rules must be tested with the emulator before deploying
|
|
- No `allow read, write: if true` — even in development
|
|
- Rule coverage: every collection must have explicit rules
|