FirestoreDB class wraps Google Cloud’s AsyncClient and provides a single, reusable configuration object that you create once at application start-up and pass to init_firestore_odm().
FirestoreDB Overview
FirestoreDB is a lightweight wrapper around google.cloud.firestore_v1.AsyncClient. Its responsibilities are:
- Creating and holding a reference to the underlying async Firestore client.
- Routing traffic to the production Firestore backend or a local emulator, depending on configuration.
- Providing a
mock_firestore_for_tests()helper that replaces the client with aMagicMockfor unit tests.
client attribute exposes the raw AsyncClient if you ever need to drop down to the SDK directly.
Constructor Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
project_id | str | ✅ | Your Google Cloud project identifier. |
database | str | None | ❌ | Firestore database ID. Defaults to the project’s default database. |
credentials | credentials object | None | ❌ | Explicit GCP credentials. When None, the Google SDK default-credentials chain is used. |
emulator_host | str | None | ❌ | Emulator host and port (e.g. "localhost:8080"). When set, all traffic is directed to the emulator. |
Production Setup
In production,FirestoreDB relies on Google’s Application Default Credentials (ADC). No explicit credentials argument is needed when your environment is properly authenticated.
- Cloud Run / GKE (workload identity)
- Local / CI with service account key
- Explicit credentials object
When running on Google Cloud infrastructure with a service account attached, ADC picks up the credentials automatically — no environment variables required.
Emulator Setup
The Firestore emulator lets you develop and run integration tests without touching a real Firestore instance. The ODM sets theFIRESTORE_EMULATOR_HOST environment variable internally when you configure an emulator host, so you never have to set it yourself.
Switching Between Emulator and Production at Runtime
If you need to toggle between the emulator and production on a runningFirestoreDB instance — for example inside a test fixture — use use_emulator() and clear_emulator().
Both
use_emulator() and clear_emulator() recreate the underlying AsyncClient immediately. Any in-flight requests on the old client will not be affected, but all subsequent calls will use the new client.Mock Firestore for Unit Tests
For unit tests that must not touch the network or the emulator,mock_firestore_for_tests() replaces db.client with a unittest.mock.MagicMock. This keeps your test suite fast and hermetic.
Registering Models
Registering models withinit_firestore_odm() does three things for each model in the list:
- Injects
_db— callsmodel.initialize_db(database)so every class method has access to the Firestore client. - Sets up field descriptors — calls
model.initialize_fields()so that class-level attribute access (e.g.User.age >= 18) produces query filter tuples. - Populates
_registered_models— stores the full list of model classes onBaseFirestoreModel._registered_models, which is consulted during cascade deletes to discover child models dynamically.
Per-Model Initialisation
Wheninit_firestore_odm() is not suitable — for example in a plugin architecture where models are discovered at runtime — you can initialise each model individually.
Why Registration Matters for Cascade Delete
When you calldocument.delete(cascade=True), the ODM calls cls._get_child_models() to find every registered model whose Settings.parent points to the current class. It then recurses through all matching documents and deletes them before deleting the parent. This traversal only works if all models were registered via init_firestore_odm().
Models
Learn how to declare Firestore document schemas with Pydantic.
Subcollections
Model parent-child document relationships and run nested queries.
