Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Use when setting up Firestore, designing schemas, doing CRUD, creating listeners, paginating queries, configuring indexes, enabling offline persistence, or writing security rules.
.claude/skills/evanca-firebase-cloud-firestore/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-04 | ✗→✓ | ▲ Improved | 62% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 197% | 0% |
| case-20 | ✗→✓ | ▲ Improved | 51% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 18% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 35% | 0% |
This skill defines how to correctly implement Cloud Firestore in Flutter applications, covering data modeling, queries, real-time updates, security rules, and scale optimization.
Use this skill when:
Choose Cloud Firestore when the app needs:
Use Realtime Database instead for simple data models requiring simple lookups and extremely low-latency synchronization (typical response times under 10ms).
flutter pub add cloud_firestoredartimport 'package:cloud_firestore/cloud_firestore.dart'; final db = FirebaseFirestore.instance; // after Firebase.initializeApp()
Location:
iOS/macOS: Consider pre-compiled frameworks to improve build times:
rubypod 'FirebaseFirestore', :git => 'https://github.com/invertase/firestore-ios-sdk-frameworks.git', :tag => 'IOS_SDK_VERSION'
Offline persistence is enabled by default on mobile. Configure cache size:
dartFirebaseFirestore.instance.settings = const Settings( persistenceEnabled: true, cacheSizeBytes: Settings.CACHE_SIZE_UNLIMITED, );
. and .. (special meaning in Firestore paths)./) in document IDs (path separators).Customer1, Customer2) — causes write hotspots.dartfinal docRef = await db.collection("users").add({ 'name': 'Ada Lovelace', 'email': 'ada@example.com', 'created_at': FieldValue.serverTimestamp(), }); print('Created document with ID: ${docRef.id}');
. [ ] * dartfinal querySnapshot = await db.collection("users").get(); for (var doc in querySnapshot.docs) { print("${doc.id} => ${doc.data()}"); }
dartfinal query = db.collection("users") .where("age", isGreaterThanOrEqualTo: 18) .orderBy("age") .limit(20); final results = await query.get();
dart// First page final first = db.collection("cities").orderBy("name").limit(25); final firstSnapshot = await first.get(); // Next page using last document as cursor final lastDoc = firstSnapshot.docs.last; final next = db.collection("cities") .orderBy("name") .startAfterDocument(lastDoc) .limit(25);
dartawait db.collection("users").doc("user_1").set({ 'name': 'Grace Hopper', 'updated_at': FieldValue.serverTimestamp(), });
dartfinal batch = db.batch(); batch.set(db.collection("cities").doc("LA"), {'name': 'Los Angeles'}); batch.update(db.collection("cities").doc("SF"), {'population': 860000}); batch.delete(db.collection("cities").doc("OLD")); await batch.commit();
dartawait db.runTransaction((transaction) async { final snapshot = await transaction.get(db.collection("counters").doc("visits")); final currentCount = snapshot.get("count") as int; transaction.update(snapshot.reference, {"count": currentCount + 1}); });
start_at to find the correct start point.dartfinal subscription = db.collection("messages") .where("room", isEqualTo: "general") .orderBy("timestamp", descending: true) .limit(50) .snapshots() .listen((querySnapshot) { for (var change in querySnapshot.docChanges) { switch (change.type) { case DocumentChangeType.added: print("New message: ${change.doc.data()}"); break; case DocumentChangeType.modified: print("Modified: ${change.doc.data()}"); break; case DocumentChangeType.removed: print("Removed: ${change.doc.id}"); break; } } }); // Detach when no longer needed: subscription.cancel();
Example rules for user-owned documents:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow read, update, delete: if request.auth != null && request.auth.uid == userId;
allow create: if request.auth != null;
}
}
}Other measured skills in the registry, with their headline benchmark lift.