Skip to content
Development
Skill

/firebase-cloud-firestore

Use when setting up Firestore, designing schemas, doing CRUD, creating listeners, paginating queries, configuring indexes, enabling offline persistence, or writing security rules.

From plugin
flutter-ai-skills
67036 skills

Claude Code

$ npx -y skills add evanca/flutter-ai-rules --skill firebase-cloud-firestore --agent claude-code

SKILL.md

firebase-cloud-firestore.SKILL.md
name: firebase-cloud-firestore
description: "Use when setting up Firestore, designing schemas, doing CRUD, creating listeners, paginating queries, configuring indexes, enabling offline persistence, or writing security rules."
license: MIT

Firebase Cloud Firestore Skill

This skill defines how to correctly implement Cloud Firestore in Flutter applications, covering data modeling, queries, real-time updates, security rules, and scale optimization.

When to Use

Use this skill when:

  • Setting up and configuring Cloud Firestore in a Flutter project.
  • Designing document and collection structure or planning subcollections.
  • Performing read, write, batch, or transaction operations.
  • Implementing real-time listeners or paginated queries.
  • Optimizing for scale and avoiding write hotspots.
  • Writing or debugging Firestore security rules.

---

1. Database Selection

Choose **Cloud Firestore** when the app needs:

  • Rich, hierarchical data models with subcollections.
  • Complex queries: chaining filters, combining filtering and sorting on a property.
  • Transactions that atomically read and write data from any part of the database.
  • High availability (typical uptime 99.999%) or critical-level reliability.
  • Automatic scaling to millions of concurrent users.

Use **Realtime Database** instead for simple data models requiring simple lookups and extremely low-latency synchronization (typical response times under 10ms).

---

2. Setup and Configuration

flutter pub add cloud_firestore

> **Security (eMudhra CA fix):** Use Dart ≥ 3.13.7 and Flutter ≥ 3.47.8 > (advisory [GHSA-frr6-h895-5pxp](https://github.com/dart-lang/sdk/security/advisories/GHSA-frr6-h895-5pxp)). > For **Apple or Windows targets using Firestore**, also upgrade > `cloud_firestore` to **≥ 7.1.0** (FlutterFire BoM ≥ 5.1.0) and run > `flutter pub upgrade`, then rebuild and redeploy.

import 'package:cloud_firestore/cloud_firestore.dart';

final db = FirebaseFirestore.instance; // after Firebase.initializeApp()

**Location:**

  • Select the database location closest to users and compute resources.
  • Use **multi-region** locations for critical apps (maximum availability and durability).
  • Use **regional** locations for lower costs and lower write latency.

**iOS/macOS:** Consider pre-compiled frameworks to improve build times:

pod '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:

FirebaseFirestore.instance.settings = const Settings(
  persistenceEnabled: true,
  cacheSizeBytes: Settings.CACHE_SIZE_UNLIMITED,
);

---

3. Document Structure

  • Avoid document IDs `.` and `..` (special meaning in Firestore paths).
  • Avoid forward slashes (`/`) in document IDs (path separators).
  • **Do not** use monotonically increasing document IDs (e.g., `Customer1`, `Customer2`) — causes write hotspots.
  • Use Firestore's **automatic document IDs** when possible:
final docRef = await db.collection("users").add({
  'name': 'Ada Lovelace',
  'email': 'ada@example.com',
  'created_at': FieldValue.serverTimestamp(),
});
print('Created document with ID: ${docRef.id}');
  • Avoid these characters in field names (require extra escaping): `.` `[` `]` `*` `` ` ``
  • Use **subcollections** within documents to organize complex, hierarchical data rather than deeply nested objects.

---

4. Indexing

  • Firestore queries are indexed by default; query performance is proportional to the result set size, not the dataset size.
  • Set **collection-level index exemptions** to reduce write latency and storage costs.
  • Disable Descending and Array indexing for fields that do not need them.
  • Exempt string fields with long values that are not used for querying.
  • Exempt fields with sequential values (e.g., timestamps) from indexing if not used in queries — avoids the 500 writes/second index limit.
  • Add single-field exemptions for TTL fields.
  • Exempt large array or map fields not used in queries — avoids the 40,000 index entries per document limit.

---

5. Read and Write Operations

Read All Documents in a Collection

final querySnapshot = await db.collection("users").get();
for (var doc in querySnapshot.docs) {
  print("${doc.id} => ${doc.data()}");
}

Query with Filters

final query = db.collection("users")
    .where("age", isGreaterThanOrEqualTo: 18)
    .orderBy("age")
    .limit(20);

final results = await query.get();

Cursor-Based Pagination

// 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);
  • **Do not use offsets for pagination** — use cursors to avoid retrieving and being billed for skipped documents.

Write with Server Timestamp

await db.collection("users").doc("user_1").set({
  'name': 'Grace Hopper',
  'updated_at': FieldValue.serverTimestamp(),
});

Batch Write (Atomic, Up to 500 Operations)

final 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();

Transaction

await 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});
});
  • Execute independent operations (e.g., a document lookup and a query) **in parallel**, not sequentially.
  • Be aware of write rate limits: ~1 write per second per document.
  • For writing
Read more
@evanca
Ships withflutter-ai-skills

36 Flutter and Dart skills your coding agent loads by itself, sourced only from official documentation. A skill is a folder with a SKILL.md file.

Stars on GitHub

Momentum

stars in total
670
Star history of evanca/flutter-ai-rules on GitHub, a chart by star-history.com

Other skills on flutter-ai-skills.

accessibility

accessibility

Use when working on accessibility, a11y, WCAG, ARIA, screen readers, keyboard nav, focus order, contrast, alt text, captions,…

bloc

bloc

Use when creating a Cubit or Bloc, modeling state with sealed classes or status enums, wiring…

dart-3-updates

dart-3-updates

Use when writing switch statements, refactoring if-else chains, creating data classes, choosing records vs classes, destructuring…

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills2w309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc2w293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react5d252k
@facebook@facebookInstall Skill

Questions about firebase-cloud-firestore.

Which coding agents can use firebase-cloud-firestore?
firebase-cloud-firestore installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.