Google Cloud Firestore Python Client

raw JSON →
2.26.0 verified Tue May 12 auth: no python install: verified

The `google-cloud-firestore` client library provides a Pythonic interface for interacting with Google Cloud Firestore. Firestore is a fully-managed, scalable NoSQL document database for mobile, web, and server development, offering real-time data synchronization and offline support. It is currently at version 2.26.0 and receives regular updates as part of the broader `google-cloud-python` client libraries.

pip install --upgrade google-cloud-firestore
error ModuleNotFoundError: No module named 'google.cloud.firestore' OR ImportError: Failed to import the Cloud Firestore library for Python.
cause The `google-cloud-firestore` library, or one of its dependencies, is not correctly installed or is not accessible in the current Python environment.
fix
Ensure the library is installed using pip: pip install google-cloud-firestore. If the issue persists, try upgrading pip and setuptools, or reinstalling grpcio: pip install --upgrade pip setuptools then pip install --no-cache-dir --force-reinstall -Iv grpcio==1.45.0 (adjust grpcio version as needed).
error AttributeError: 'CollectionReference' object has no attribute 'set' (or 'doc', 'orderBy', 'stream')
cause You are attempting to use a method meant for a `DocumentReference` (like `set()`) or using an incorrect method name on a `CollectionReference` object. `CollectionReference` objects manage collections, while `DocumentReference` objects manage individual documents. Also, method names often use underscores in Python (e.g., `order_by` instead of `orderBy`).
fix
To create or update a document, first get a DocumentReference using .document('document_id'). For example, db.collection('my_collection').document('my_doc').set({'field': 'value'}). To add a new document with an auto-generated ID to a collection, use .add(): db.collection('my_collection').add({'field': 'value'}). For ordering, use order_by() instead of orderBy.
error AttributeError: 'NoneType' object has no attribute 'to_dict' (or 'get', 'exists')
cause This error typically occurs when you call `.get()` on a `DocumentReference`, but the document does not exist in Firestore. In such cases, `DocumentReference.get()` returns `None`, and subsequent attempts to access attributes like `to_dict()` or `exists` on `None` will raise this error.
fix
Always check if the DocumentSnapshot object exists before attempting to access its data. For example: doc_ref = db.collection('users').document('user_id'); doc_snapshot = doc_ref.get(); if doc_snapshot.exists: print(doc_snapshot.to_dict()) else: print('Document not found.').
error google.api_core.exceptions.PermissionDenied: 403 Missing or insufficient permissions. OR google.auth.exceptions.DefaultCredentialsError: Your default credentials were not found.
cause Your application lacks the necessary authentication credentials or IAM permissions to access the Firestore database. This can happen if service account keys are misconfigured, environment variables (like `GOOGLE_APPLICATION_CREDENTIALS`) are not set, or the assigned service account does not have the 'Cloud Datastore User' or 'Cloud Datastore Owner' role.
fix
Ensure your environment is authenticated correctly. For local development, set the GOOGLE_APPLICATION_CREDENTIALS environment variable to the path of your service account JSON key file. For deployment on Google Cloud (e.g., Cloud Functions, App Engine), ensure the service account associated with the environment has the appropriate Firestore roles (e.g., 'Cloud Datastore User').
breaking Version 2.0.0 introduced significant interface changes due to a next-gen code generator. Method calls shifted from positional/keyword parameters to a single `request` parameter. Code using `google.cloud.firestore_v1.gapic` namespaces will likely be incompatible. Python 3.6+ became a hard requirement.
fix Review the 2.0.0 migration guide in the official documentation. The library may ship `fixup_firestore_v1_keywords.py` and `fixup_firestore_admin_v1_keywords.py` scripts to assist with code modification.
gotcha The Firestore client can hang indefinitely on authentication errors, especially when local `gcloud CLI` authentication tokens expire. This can manifest as scripts freezing without clear error messages.
fix Ensure that Application Default Credentials are valid and up-to-date. For local development, run `gcloud auth application-default login` regularly. For production, ensure service account permissions and key validity.
gotcha Queries involving multiple fields or specific operators (like `array-contains-any`, `in`) often require a composite index to be created in the Firestore console. Failing to do so results in a `FailedPrecondition: 400 The query requires an index` error at runtime.
fix When encountering index errors, follow the link provided in the error message to the Firebase/Google Cloud console to create the necessary composite index. Plan for index creation during development for complex queries.
gotcha Confusing `google-cloud-firestore` with `firebase-admin`. While `firebase-admin` internally uses `google-cloud-firestore` for its Firestore interactions, they serve different purposes. `google-cloud-firestore` is the lower-level client for general GCP projects, while `firebase-admin` is tailored for Firebase-specific services and authentication, particularly for server-side code in a Firebase project.
fix Choose the appropriate library based on your project's needs: `google-cloud-firestore` for direct Google Cloud integration, `firebase-admin` for projects heavily leveraging Firebase services (Authentication, Realtime Database, etc.).
deprecated Support for older Python versions is progressively dropped. As of `firebase-admin` v7.0.0, Python 3.7 and 3.8 were dropped, and 3.9 was deprecated. `google-cloud-firestore` itself requires Python >= 3.7.
fix Ensure your Python environment is running Python 3.7 or higher. For new projects, consider Python 3.10+ for better forward compatibility.
python os / libc status wheel install import disk
3.10 alpine (musl) wheel - 1.92s 72.7M
3.10 alpine (musl) - - 1.83s 71.5M
3.10 slim (glibc) wheel 6.2s 1.12s 71M
3.10 slim (glibc) - - 1.36s 69M
3.11 alpine (musl) wheel - 2.42s 77.9M
3.11 alpine (musl) - - 2.87s 76.6M
3.11 slim (glibc) wheel 5.3s 1.63s 76M
3.11 slim (glibc) - - 1.58s 74M
3.12 alpine (musl) wheel - 2.54s 69.3M
3.12 alpine (musl) - - 2.80s 68.0M
3.12 slim (glibc) wheel 4.5s 2.01s 67M
3.12 slim (glibc) - - 2.05s 66M
3.13 alpine (musl) wheel - 2.34s 68.9M
3.13 alpine (musl) - - 2.62s 67.6M
3.13 slim (glibc) wheel 4.6s 1.89s 67M
3.13 slim (glibc) - - 2.10s 65M
3.9 alpine (musl) wheel - 1.77s 72.8M
3.9 alpine (musl) - - 1.66s 71.6M
3.9 slim (glibc) wheel 6.8s 1.27s 71M
3.9 slim (glibc) - - 1.17s 69M

This quickstart demonstrates how to initialize the Firestore client, add a new document to a collection, retrieve a single document, and perform a basic query for documents. It assumes 'Application Default Credentials' are set up (e.g., via `gcloud auth application-default login` or by setting the `GOOGLE_APPLICATION_CREDENTIALS` environment variable to a service account key file path).

import os
from google.cloud import firestore

# Ensure GOOGLE_APPLICATION_CREDENTIALS environment variable is set
# e.g., export GOOGLE_APPLICATION_CREDENTIALS="/path/to/your/service_account_key.json"
# Or set programmatically (less secure for production):
# from google.oauth2 import service_account
# credentials = service_account.Credentials.from_service_account_file('path/to/your/service_account_key.json')
# db = firestore.Client(credentials=credentials)

def quickstart_firestore():
    # Initialize Firestore DB client. It automatically uses Application Default Credentials.
    # Make sure you have created a Firestore database in your GCP project first.
    db = firestore.Client()

    # Add a new document to a collection 'users'
    doc_ref = db.collection('users').document('alovelace')
    doc_ref.set({
        'first': 'Ada',
        'last': 'Lovelace',
        'born': 1815
    })
    print(f"Added document: {doc_ref.id}")

    # Read a single document
    doc = doc_ref.get()
    if doc.exists:
        print(f"Document data: {doc.to_dict()}")
    else:
        print("No such document!")

    # Query for documents
    users_ref = db.collection('users')
    docs = users_ref.where('born', '<', 1900).stream()
    print("Users born before 1900:")
    for doc in docs:
        print(f"{doc.id} => {doc.to_dict()}")

if __name__ == '__main__':
    # Placeholder for environment variable setup for local testing
    # In production environments (e.g., GCE, Cloud Functions), credentials are often auto-discovered.
    if not os.environ.get('GOOGLE_APPLICATION_CREDENTIALS'):
        print("WARNING: GOOGLE_APPLICATION_CREDENTIALS environment variable not set. "
              "Using default credentials if available, or client might fail.")
    quickstart_firestore()