GCP for DevOps — Firestore

2 minute read

Firestore

Firestore is a serverless, NoSQL document database with real-time sync, automatic scaling, and strong consistency. It’s ideal for serverless backends, mobile apps, and IoT data.

Firestore Modes

Mode Description Use Case
Native Full Firestore features (real-time, offline) Mobile/web apps, real-time
Datastore Datastore-compatible mode Legacy apps, batch processing

Create a Firestore Database

# Create a Firestore database (Native mode)
$ gcloud firestore databases create \
    --location=us-central1 \
    --type=firestore-native

# List databases
$ gcloud firestore databases list

Data Model

Firestore Data Model:
┌─────────────────────────────────────────┐
│ Database                                 │
│ ├── Collection: users                    │
│ │   ├── Document: user123                │
│ │   │   ├── name: "Alice"               │
│ │   │   ├── email: "alice@example.com"   │
│ │   │   └── Subcollection: orders        │
│ │   │       ├── Document: order456       │
│ │   │       │   ├── total: 99.99         │
│ │   │       │   └── status: "shipped"    │
│ │   │       └── Document: order789       │
│ │   └── Document: user456                │
│ └── Collection: products                 │
│     ├── Document: prod001                │
│     └── Document: prod002                │
└─────────────────────────────────────────┘

CRUD Operations (Python)

from google.cloud import firestore

db = firestore.Client()

# Create / Set a document
db.collection("users").document("user123").set({
    "name": "Alice",
    "email": "alice@example.com",
    "created_at": firestore.SERVER_TIMESTAMP,
})

# Read a document
doc = db.collection("users").document("user123").get()
if doc.exists:
    print(doc.to_dict())

# Update a document
db.collection("users").document("user123").update({
    "email": "alice@newdomain.com",
})

# Delete a document
db.collection("users").document("user123").delete()

# Query documents
users = (
    db.collection("users")
    .where("name", "==", "Alice")
    .order_by("created_at")
    .limit(10)
    .stream()
)
for user in users:
    print(f"{user.id} => {user.to_dict()}")

CRUD Operations (Node.js)

const { Firestore } = require('@google-cloud/firestore');
const db = new Firestore();

// Create
await db.collection('users').doc('user123').set({
  name: 'Alice',
  email: 'alice@example.com',
  createdAt: Firestore.FieldValue.serverTimestamp(),
});

// Read
const doc = await db.collection('users').doc('user123').get();
console.log(doc.data());

// Query
const snapshot = await db.collection('users')
  .where('name', '==', 'Alice')
  .limit(10)
  .get();
snapshot.forEach(doc => console.log(doc.id, doc.data()));

Security Rules

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Users can only read/write their own data
    match /users/{userId} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
    }

    // Products are publicly readable
    match /products/{productId} {
      allow read: if true;
      allow write: if request.auth != null && request.auth.token.admin == true;
    }
  }
}

Indexes

Firestore requires composite indexes for queries with multiple filters or ordering.

# Create a composite index
$ gcloud firestore indexes composite create \
    --collection-group=orders \
    --field-config=field-path=status,order=ASCENDING \
    --field-config=field-path=created_at,order=DESCENDING

# List indexes
$ gcloud firestore indexes composite list

Backup and Export

# Export all data
$ gcloud firestore export gs://my-firestore-backups/export-$(date +%Y%m%d)

# Export specific collections
$ gcloud firestore export gs://my-firestore-backups/users-backup \
    --collection-ids=users,orders

# Import data
$ gcloud firestore import gs://my-firestore-backups/export-20260330

Common Mistakes

Mistake Why It’s Wrong Fix
Deep nesting (>3 levels) Hard to query, complex rules Flatten with root-level collections
No composite indexes Queries fail at runtime Create indexes for compound queries
No security rules Data exposed Always configure security rules
Large documents (>1 MB) Hits size limit Split into subcollections
No regular backups Data loss risk Schedule exports to GCS

Quick Reference

Command Description
gcloud firestore databases create Create database
gcloud firestore export gs://BUCKET/PATH Export data
gcloud firestore import gs://BUCKET/PATH Import data
gcloud firestore indexes composite create Create index
gcloud firestore indexes composite list List indexes

Next → Eventarc & Workflows

Updated: