Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions packages/cloud_firestore/cloud_firestore/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down