How to Export a Firestore Collection to JSON (and Import It Back)
Updated
You want a Firestore collection as a JSON file: to inspect it, seed another environment, move it to a different project or database, or keep a quick snapshot before a risky change. There are three ways to do it, and they suit different jobs.
Option 1: Managed export (gcloud)
gcloud firestore export gs://my-bucket/backups/2026-09-26 \ --collection-ids=orders --project=my-project
- Pros: handles any size, includes subcollections, and imports back with
gcloud firestore import. - Cons: the output is a LevelDB-based format in Cloud Storage, not JSON; it needs a bucket, the right IAM roles, and a billing-enabled project.
- Use it for: backups and large migrations. For ongoing protection, also consider scheduled backups and point-in-time recovery.
Option 2: A script with the Admin SDK
Page through the collection with a cursor and write each document out:
const out = [];
let last;
for (;;) {
let q = db.collection("orders").orderBy("__name__").limit(500);
if (last) q = q.startAfter(last);
const page = await q.get();
page.docs.forEach((d) => out.push({ id: d.id, ...d.data() }));
if (page.size < 500) break;
last = page.docs[page.docs.length - 1];
}
fs.writeFileSync("orders.json", JSON.stringify(out, null, 2));- Pros: full control, and JSON output.
- Cons:
JSON.stringifyloses Firestore types. Timestamps become objects, references become circular or huge structures, and large integers lose precision. Importing that file back stores the wrong types unless you write custom serialization (see why types matter). - Every document is one read, so exporting a million documents costs a million reads.
Option 3: Export and import in Firewatch
Firewatch exports a collection from your browser to a JSON file that keeps every Firestore type, using tagged values such as {"$timestamp": "..."} and {"$ref": "users/alice"}. Importing that file into another project, database, or collection restores the same types.
- Open the collection and click Export. Pages are read with cursors, and you can cancel at any time.
- In the target collection, click Import and choose the file.
- Firewatch validates every document before writing anything, and tells you if the file came from somewhere else.
- By default, documents that already exist are skipped. Turning on overwrite replaces them. Writes happen in batches of 500, and you get a report of what was written, skipped, and failed.
Firewatch exports one collection at a time and doesn't include subcollections. For full-database backups, use the managed export. Your data goes directly between Google and your browser and is never uploaded to Firewatch.
Which should you use?
| Goal | Best option |
|---|---|
| Disaster-recovery backups | Managed export, scheduled backups, or point-in-time recovery |
| Copy a collection to another project, keeping types | Firewatch export and import |
| Inspect data as JSON | Firewatch export |
| Transform data during a migration | An Admin SDK script with proper type handling |
Need permission to export? Reading requires at least the roles/datastore.viewer role, and importing requires roles/datastore.user. See Firestore IAM roles.