Restore Firestore data from a backup using the gcloud firestore import command pointed at a Google Cloud Storage bucket containing a previous export. For full database restores, run gcloud firestore import gs://your-bucket/export-folder. For selective collection restores, add the --collection-ids flag. Firebase also offers Point-in-Time Recovery (PITR) on Blaze plan databases, which lets you restore to any second within the last 7 days without needing a prior export.
Restoring Firestore Data from Backup
Accidental data deletion, bad deployments, or security rule misconfiguration can corrupt your Firestore data. If you have a previous backup created with gcloud firestore export, you can import it back into your database. This tutorial walks through restoring from a Cloud Storage backup, restoring specific collections, using PITR for recent incidents, and verifying the restore completed correctly.
Prerequisites
- A Firebase project on the Blaze plan
- Google Cloud CLI (gcloud) installed and authenticated
- A previous Firestore export in a Google Cloud Storage bucket
- IAM roles: Cloud Datastore Import Export Admin and Storage Admin
Step-by-step guide
Locate your backup in Cloud Storage
Locate your backup in Cloud Storage
Before restoring, identify the backup you want to import. Firestore exports are stored in Google Cloud Storage buckets as folders containing metadata files and document data. List the contents of your backup bucket to find the export folder. Each export creates a folder with a timestamp or name you specified during the export. The folder contains an overall_export_metadata file that the import command needs.
1# List all exports in your backup bucket2gcloud storage ls gs://your-backup-bucket/34# List contents of a specific export folder5gcloud storage ls gs://your-backup-bucket/2026-03-28-daily-backup/67# You should see an overall_export_metadata file8# gs://your-backup-bucket/2026-03-28-daily-backup/overall_export_metadata9# gs://your-backup-bucket/2026-03-28-daily-backup/all_namespaces/Expected result: You can see the export folder contents including the overall_export_metadata file, confirming the backup is valid.
Restore the full database from backup
Restore the full database from backup
Run the gcloud firestore import command with the path to the export folder (not the metadata file itself). The import is a long-running operation — it runs in the background on Google's servers and can take minutes to hours depending on the database size. The command returns an operation ID you can use to check progress. Important: importing does NOT delete existing documents that are not in the backup. It overwrites documents that exist in both the backup and the live database.
1# Import the full backup2gcloud firestore import gs://your-backup-bucket/2026-03-28-daily-backup34# The command outputs an operation ID like:5# operation: projects/your-project/databases/(default)/operations/abc12367# Check import progress8gcloud firestore operations describe projects/your-project/databases/(default)/operations/abc123Expected result: The import operation starts and runs in the background. The describe command shows the operation status as RUNNING or DONE.
Restore specific collections only
Restore specific collections only
If you only need to restore certain collections rather than the entire database, use the --collection-ids flag. This is useful when a bug corrupted one collection but the rest of your data is fine. You can specify multiple collection IDs separated by commas. The export must have been created without collection filters (a full export) or must include the collections you want to restore.
1# Restore only the 'users' and 'orders' collections2gcloud firestore import gs://your-backup-bucket/2026-03-28-daily-backup \3 --collection-ids=users,orders45# Restore a single collection6gcloud firestore import gs://your-backup-bucket/2026-03-28-daily-backup \7 --collection-ids=productsExpected result: Only the specified collections are restored from the backup. Other collections in the database remain unchanged.
Use Point-in-Time Recovery (PITR) for recent data loss
Use Point-in-Time Recovery (PITR) for recent data loss
If the data loss happened within the last 7 days and your database has PITR enabled, you can restore to any second within that window without needing a prior export. PITR is available on Blaze plan and must be enabled before the incident occurs. Use the Firebase Console or gcloud to initiate a PITR restore to a new database, then migrate the data back to your primary database.
1# Check if PITR is enabled on your database2gcloud firestore databases describe --database="(default)"34# Enable PITR (must be done BEFORE data loss occurs)5gcloud firestore databases update --database="(default)" \6 --enable-pitr78# Restore to a point in time (creates a new database)9# Use ISO 8601 timestamp format10gcloud firestore databases restore \11 --source-database="(default)" \12 --destination-database="restored-db" \13 --snapshot-time="2026-03-27T14:30:00Z"Expected result: A new database named 'restored-db' is created containing the exact state of your data at the specified timestamp.
Verify the restored data
Verify the restored data
After the import operation completes, verify the data was restored correctly. Check document counts in key collections, spot-check specific documents, and test your application against the restored data. If you restored specific collections, verify that only those collections were affected and that other data remains intact.
1import { initializeApp } from 'firebase/app'2import { getFirestore, collection, getCountFromServer, doc, getDoc } from 'firebase/firestore'34const app = initializeApp({ /* your config */ })5const db = getFirestore(app)67async function verifyRestore() {8 // Check document counts9 const usersCount = await getCountFromServer(collection(db, 'users'))10 console.log('Users collection count:', usersCount.data().count)1112 const ordersCount = await getCountFromServer(collection(db, 'orders'))13 console.log('Orders collection count:', ordersCount.data().count)1415 // Spot-check a specific document16 const testDoc = await getDoc(doc(db, 'users', 'known-user-id'))17 if (testDoc.exists()) {18 console.log('Test user data:', testDoc.data())19 } else {20 console.warn('Test user document not found — restore may be incomplete.')21 }22}Expected result: Collection counts match expected values from the backup, and spot-checked documents contain the correct data.
Complete working example
1import { initializeApp } from 'firebase/app'2import {3 getFirestore,4 collection,5 getCountFromServer,6 doc,7 getDoc,8 getDocs,9 query,10 limit,11 orderBy12} from 'firebase/firestore'1314const app = initializeApp({15 apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY!,16 authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN!,17 projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID!18})1920const db = getFirestore(app)2122interface RestoreVerification {23 collection: string24 count: number25 sampleDoc: Record<string, any> | null26}2728async function verifyCollectionRestore(29 collectionName: string30): Promise<RestoreVerification> {31 // Get total document count32 const countResult = await getCountFromServer(33 collection(db, collectionName)34 )3536 // Get a sample document for spot-checking37 const sampleQuery = query(38 collection(db, collectionName),39 orderBy('__name__'),40 limit(1)41 )42 const sampleSnapshot = await getDocs(sampleQuery)43 const sampleDoc = sampleSnapshot.empty44 ? null45 : { id: sampleSnapshot.docs[0].id, ...sampleSnapshot.docs[0].data() }4647 return {48 collection: collectionName,49 count: countResult.data().count,50 sampleDoc51 }52}5354async function verifyFullRestore(55 collections: string[]56): Promise<RestoreVerification[]> {57 const results = await Promise.all(58 collections.map((name) => verifyCollectionRestore(name))59 )6061 for (const result of results) {62 console.log(63 `${result.collection}: ${result.count} documents`,64 result.sampleDoc ? '(sample verified)' : '(empty)'65 )66 }6768 return results69}7071// Usage: verify key collections after restore72verifyFullRestore(['users', 'orders', 'products', 'settings'])Common mistakes when restoring Firestore from a Backup
Why it's a problem: Expecting import to delete documents not present in the backup — import only overwrites matching documents
How to avoid: If you need a clean restore, delete the collection first using the Firebase CLI (firebase firestore:delete --all-collections) before importing. Be extremely careful with this approach in production.
Why it's a problem: Trying to import from a backup created with --collection-ids and expecting collections not in the export to be available
How to avoid: You can only restore collections that were included in the original export. Use full-database exports for complete backup coverage.
Why it's a problem: Not having the correct IAM roles, causing 'permission denied' during import
How to avoid: The account running the import needs Cloud Datastore Import Export Admin and Storage Object Viewer roles. Assign these in the Google Cloud Console under IAM.
Why it's a problem: Assuming PITR is available without having enabled it before the incident
How to avoid: PITR must be enabled before data loss occurs. Enable it proactively: gcloud firestore databases update --database="(default)" --enable-pitr. PITR retains data for 7 days.
Best practices
- Schedule automated daily backups with Cloud Scheduler so you always have a recent export to restore from
- Test your restore process periodically by importing into a separate Firebase project to verify backups are valid
- Enable PITR on production databases as an additional safety net for data loss within the last 7 days
- Use selective collection restores when possible to minimize the impact on unaffected data
- Verify restored data by checking document counts and spot-checking key documents immediately after import
- Keep backup bucket retention policies to maintain at least 30 days of daily backups
- Document your restore procedure in a runbook so the team can execute it quickly during an incident
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
I accidentally deleted a Firestore collection in my Firebase project. I have a gcloud export backup in a Cloud Storage bucket from yesterday. Walk me through the complete restore process using gcloud firestore import, including how to restore just the deleted collection and how to verify the data was restored correctly.
Write a Firebase Cloud Function that runs a daily automated Firestore backup to Cloud Storage using the Admin SDK and gcloud, with retention of 30 days. Include a verification step that checks the export metadata. Also show the gcloud commands needed to restore from any of these backups.
Frequently asked questions
Does a Firestore import overwrite existing documents?
Yes, for documents that exist in both the backup and the live database, the import overwrites the live version with the backup version. Documents that exist only in the live database are not affected — they remain as-is. Import does not delete anything.
How long does a Firestore restore take?
Restore time depends on the size of the backup. Small databases (under 1 GB) typically restore in a few minutes. Large databases (10+ GB) can take 30 minutes to several hours. The operation runs on Google's servers and does not require your machine to stay connected.
Can I restore to a different Firebase project?
Yes. As long as the target project has access to the Cloud Storage bucket containing the export, you can run gcloud firestore import from any project. Grant the target project's service account Storage Object Viewer access on the bucket.
Is Point-in-Time Recovery available on the Spark free plan?
No. PITR is only available on the Blaze pay-as-you-go plan. It must be enabled before data loss occurs and provides a 7-day recovery window. There is an additional storage cost for PITR data retention.
Can I restore subcollections from a backup?
Yes. If the export was a full database export, all subcollections are included. If you used --collection-ids during export, only top-level collections with those IDs are included — their subcollections are included automatically, but subcollections of other collections are not.
Can RapidDev help set up automated Firestore backup and restore procedures?
Yes. RapidDev can configure automated daily backups, retention policies, restore runbooks, and PITR for your Firebase project so your data is always recoverable.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation