diff --git a/packages/cloud_firestore/cloud_firestore/README.md b/packages/cloud_firestore/cloud_firestore/README.md index 7531ebef9270..38a939bf7a95 100755 --- a/packages/cloud_firestore/cloud_firestore/README.md +++ b/packages/cloud_firestore/cloud_firestore/README.md @@ -16,6 +16,63 @@ To get started with Cloud Firestore for Flutter, please [see the documentation]( To use this plugin, please visit the [Firestore Usage documentation](https://firebase.google.com/docs/firestore/manage-data/add-data) +## Using Cloud Firestore with Isolates + +Cloud Firestore (like most FlutterFire plugins) talks to native code through +platform channels. Those channels are only available on the **main isolate**. + +That means you **cannot** call Firestore APIs inside `compute()`, +`Isolate.run()`, or a background isolate spawned with `Isolate.spawn()`: + +```dart +// ❌ This will fail — Firestore cannot use platform channels off the main isolate. +await compute((_) async { + final snapshot = await FirebaseFirestore.instance.collection('users').get(); + return snapshot.docs.length; +}, null); +``` + +### Recommended pattern + +1. **Fetch on the main isolate** (where Firebase is initialized). +2. Convert results to **plain Dart data** (`Map` / `List` / your own model). +3. **Process** that data in a background isolate if the work is CPU-heavy. + +```dart +// ✅ Fetch on the main isolate +final snapshot = + await FirebaseFirestore.instance.collection('products').get(); + +// Pass only sendable data into the isolate +final raw = snapshot.docs.map((doc) => doc.data()).toList(); + +final processed = await Isolate.run(() { + // Heavy CPU work only — no Firebase / plugin calls here + return raw.map((data) { + final price = (data['price'] as num?)?.toDouble() ?? 0; + return price * 1.2; // example transform + }).toList(); +}); +``` + +### Why DocumentSnapshot / QuerySnapshot are not enough + +`DocumentSnapshot`, `QueryDocumentSnapshot`, and similar types are **not** safe +to send across isolates. Always extract `data()` (or map to your own immutable +model) before calling `Isolate.run` / `compute`. + +### Streams and listeners + +Realtime listeners (`snapshots()`) must also be attached on the main isolate. +If you need background work per event, map each event to plain data first, then +offload processing. + +### Related issues + +- [#3124](https://github.com/firebase/flutterfire/issues/3124) +- [#4129](https://github.com/firebase/flutterfire/issues/4129) +- [#4846](https://github.com/firebase/flutterfire/issues/4846) + ## Issues and feedback Please file FlutterFire specific issues, bugs, or feature requests in our [issue tracker](https://github.com/firebase/flutterfire/issues/new).