Restore the (default) Firestore database on ${PROJECT} from a managed backup.
userscollection corrupted / accidentally deleted (encrypted API keys lost → all users must re-register)oauth_statecollection corrupted (in-flight OAuth flows break; users retry, recover)- Faulty migration overwrote data
Cache data (cache.db) is not in Firestore — it lives in GCS and is
regenerated by the self-hosted daily refresh pipeline (see
scripts/daily_fetch.py and scripts/gcs_export_cache.py).
Two managed backup schedules are active on (default):
| Recurrence | Retention | Purpose |
|---|---|---|
| Daily | 7 days | Recent point-in-time restores |
| Weekly (Sunday) | 14 weeks (~3 months) | Medium-term safety net |
List schedules:
gcloud firestore backups schedules list \
--database='(default)' --project=${PROJECT}List backups:
gcloud firestore backups list --project=${PROJECT}Firestore managed backups restore to a new database — you cannot
overwrite (default) in place. Recovery is a two-step swap.
gcloud firestore backups list --project=${PROJECT} \
--format="table(name,snapshotTime,state,database,expireTime)"Copy the full resource name (projects/${PROJECT}/locations/<loc>/backups/<id>).
BACKUP='projects/${PROJECT}/locations/<LOCATION>/backups/<id>'
gcloud firestore databases restore \
--source-backup="$BACKUP" \
--destination-database='restore-YYYYMMDD' \
--project=${PROJECT}Wait for the operation to finish (gcloud firestore operations list).
# Spot-check a known user record exists
gcloud firestore documents list \
--database=restore-YYYYMMDD \
--collection=users --limit=3 --project=${PROJECT}Point the application at the restored database, or export+import back
into (default). For small collections (users, oauth_state — tens
of records) it is fastest to:
- Update
FIRESTORE_DATABASE(or equivalent) on Cloud Run to point atrestore-YYYYMMDDand redeploy via CD. - Once stable, rename/repoint back at leisure.
gcloud firestore databases delete restore-YYYYMMDD --project=${PROJECT}Run steps 1–3 against a recent backup at least once per quarter to confirm the procedure still works and the schedules are still active. Delete the scratch database at the end.
Managed backups are charged per GiB-month of storage. For ${PROJECT}
the data is small (< 1 MiB) so the cost is negligible.