Firexport指南

如何將 Firestore 資料匯出成 JSON

Realtime Database 在 Firebase 控制台裡有「匯出 JSON」按鈕,Firestore 沒有。要把 Firestore 文件以 JSON 形式匯出,有三種實用的方法,從一個查詢的結果到包含子集合的整個集合都能涵蓋。

更新於 2026年9月24日。 方法 1 中的擴充功能 Firexport 是我們開發的。方法 2 和 3 不需要它。

簡短回答

  • 現在就要某一個查詢的結果: 在控制台的查詢建構工具(Query builder)中執行它,再用瀏覽器擴充功能匯出。 方法 1
  • 含子集合的集合,或需要可重複的匯出: 一段簡短的 Admin SDK 指令碼。 方法 2
  • 大型集合中的每一份文件,或者你已經在用 BigQuery: 用 gcloud 代管匯出,再透過 BigQuery 產生 JSON。 方法 3
1. 控制台 + 擴充功能2. Admin SDK 指令碼3. gcloud + BigQuery
準備工作安裝一個 Chrome 擴充功能Node.js 和 Google Cloud 憑證Cloud Storage 值區和 BigQuery 資料集
需要啟用計費不需要不需要需要(Blaze 方案)
檔案一個 JSON 陣列一個 JSON 陣列換行分隔的 JSON,每行一份文件
子集合另外匯出,作為集合群組查詢巢狀放在每份文件之下(選用)另外匯出,每個集合 ID 一張資料表
時間戳記依控制台顯示的樣子(Advanced 為 ISO 8601)ISO 8601BigQuery 時間戳記文字

1. 用 Firexport 從 Firebase 控制台匯出

Firebase 控制台的 Firestore 頁面有一個查詢建構工具(Query builder),可以執行查詢並把結果顯示在 表格中,但沒有任何下載它們的方法。Firexport 是一款免費的 Chrome 擴充功能,會在這些結果旁邊加入一個「匯出」按鈕。

  1. 從 Chrome 線上應用程式商店安裝 Firexport。
  2. 在 Firebase 控制台開啟 Firestore Database,從面板檢視(Panel view)切換到查詢建構工具(Query builder)(「資料」分頁的右上角)。
  3. 在查詢範圍(Query scope)和路徑(Path)下選擇集合,需要的話加入篩選條件或限制, 然後按一下執行(Run)。
  4. 開啟匯出按鈕旁的 ⋮ 選單並選擇匯出為 JSON。Firexport 會走過結果的每一頁,下載一個 JSON 檔案。(「匯出」按鈕本身儲存的是 CSV。)
Firebase 控制台中的 Firestore 查詢建構工具,以及 Firexport 在查詢結果上方加入的「匯出」按鈕
「匯出」按鈕及其 ⋮ 選單位於查詢建構工具結果的上方。

檔案是一個 JSON 陣列,每份文件一個物件:先是 Document ID 鍵,然後是文件的欄位。數字、布林值和 null 保持它們的 JSON 型別,對應和陣列以巢狀形式輸出。免費版和 Advanced 的差別在於控制台只以文字顯示的那些值:

免費版——時間戳記、地理位置點和參照依控制台顯示的樣子:

[
  {
    "Document ID": "2PomjkgoCISvwnlGrypP",
    "name": "firexport",
    "count": 1,
    "tags": ["dev", "export"],
    "settings": { "theme": "dark", "beta": true },
    "createdAt": "August 24, 2026 at 1:16:09 PM UTC+9",
    "location": "[37.5665° N, 126.978° E]",
    "owner": "/users/u1"
  }
]

Advanced(一次性授權)——同樣的值,從控制台已載入的資料中還原:

[
  {
    "Document ID": "2PomjkgoCISvwnlGrypP",
    "name": "firexport",
    "count": 1,
    "tags": ["dev", "export"],
    "settings": { "theme": "dark", "beta": true },
    "createdAt": "2026-08-24T04:16:09.012207Z",
    "location": { "latitude": 37.5665, "longitude": 126.978 },
    "owner": "projects/my-app/databases/(default)/documents/users/u1"
  }
]

在免費版中,控制台文字無法重新解析成 JSON 的對應或陣列(例如被控制台用「…」截斷的那些)會保留為字串。Advanced 會把它們完整寫出。無論哪種,都不需要服務帳戶金鑰,也不需要設定計費:它在你已登入的控制台工作階段中執行,檔案在 瀏覽器內產生。它可在 Chrome 及其他以 Chromium 為基礎的瀏覽器中執行。

不用指令碼、不用服務帳戶金鑰,直接從控制台把你的下一個 Firestore 查詢匯出成 JSON。

加到 Chrome — 免費

2. 用 Admin SDK 指令碼匯出

一段使用 Firebase Admin SDK 的簡短 Node.js 指令碼可以匯出整個集合,還能深入子集合,這是另外兩種方法都做不到的。 它需要一個能讀取 Firestore 的帳戶:專案 Owner 或 Editor,或者 Cloud Datastore Viewer 角色。

  1. 安裝 SDK:npm install firebase-admin
  2. 登入以取得本機憑證:gcloud auth application-default login。在伺服器上,改為讓 GOOGLE_APPLICATION_CREDENTIALS 指向服務帳戶金鑰。
  3. 把下面的指令碼存成 export-to-json.mjs,替換 your-project-id,然後執行 node export-to-json.mjs users。加上 --subcollections 可以包含每份文件的子集合。
// Usage: node export-to-json.mjs users [--subcollections]   → writes users.json
import { writeFileSync } from 'node:fs';
import { initializeApp } from 'firebase-admin/app';
import {
  getFirestore,
  FieldPath,
  Timestamp,
  GeoPoint,
  DocumentReference,
} from 'firebase-admin/firestore';

initializeApp({ projectId: 'your-project-id' });
const db = getFirestore();
const [collection, flag] = process.argv.slice(2);
if (!collection) throw new Error('Usage: node export-to-json.mjs <collection> [--subcollections]');
const withSubcollections = flag === '--subcollections';

// Firestore types become JSON values: timestamps as ISO 8601, references as paths.
function plain(value) {
  if (value instanceof Timestamp) return value.toDate().toISOString();
  if (value instanceof DocumentReference) return value.path;
  if (value instanceof GeoPoint) return { latitude: value.latitude, longitude: value.longitude };
  if (value instanceof Uint8Array) return Buffer.from(value).toString('base64');
  if (Array.isArray(value)) return value.map(plain);
  if (value && typeof value === 'object') {
    return Object.fromEntries(Object.entries(value).map(([key, v]) => [key, plain(v)]));
  }
  return value;
}

// Read a collection 1,000 documents at a time. With --subcollections, each document also gets its
// subcollections under "__collections__", read the same way.
async function readCollection(ref) {
  const docs = [];
  let last;
  while (true) {
    let query = ref.orderBy(FieldPath.documentId()).limit(1000);
    if (last) query = query.startAfter(last);
    const page = await query.get();
    if (page.empty) break;
    for (const doc of page.docs) {
      const row = { documentId: doc.id, ...plain(doc.data()) };
      if (withSubcollections) {
        for (const sub of await doc.ref.listCollections()) {
          row.__collections__ ??= {};
          row.__collections__[sub.id] = await readCollection(sub);
        }
      }
      docs.push(row);
    }
    last = page.docs[page.docs.length - 1];
  }
  return docs;
}

const docs = await readCollection(db.collection(collection));
writeFileSync(`${collection}.json`, JSON.stringify(docs, null, 2));
console.log(`Wrote ${docs.length} documents to ${collection}.json`);
  • 使用 --subcollections 時,每份擁有子集合的文件都會得到一個存放它們的 __collections__ 鍵,並依實際深度巢狀。尋找子集合每份文件要多發一次要求,所以大型集合會更慢。
  • 本身不存在的文件(控制台把它的 ID 顯示為斜體)之下的子集合,從父集合是搆不到的。這類子集合請依集合群組匯出。
  • 指令碼在寫入檔案之前會把所有內容放在記憶體中。如果有數百萬份文件,請使用方法 3。

3. 用 gcloud 和 BigQuery 匯出

Firestore 的代管匯出會把備份以 Firestore 自己的格式寫入 Cloud Storage,而不是 JSON。BigQuery 可以載入這種格式並 以 JSON 重新寫出。這是大型集合的路線,但需要啟用計費(Blaze 方案),以及執行匯出和寫入值區的權限。Google 的匯出和匯入文件列出了所需的角色。

# 1. Export one collection. BigQuery only loads exports made with --collection-ids.
gcloud firestore export gs://YOUR_BUCKET/users-export --collection-ids=users

# 2. Load it into a BigQuery dataset in the same location as the bucket.
bq --location=US mk --dataset firestore_export
bq load --source_format=DATASTORE_BACKUP firestore_export.users \
  gs://YOUR_BUCKET/users-export/all_namespaces/kind_users/all_namespaces_kind_users.export_metadata

# 3. Write it out as newline-delimited JSON and download it.
bq extract --destination_format=NEWLINE_DELIMITED_JSON firestore_export.users gs://YOUR_BUCKET/users.json
gcloud storage cp gs://YOUR_BUCKET/users.json .
  • 檔案是換行分隔的 JSON:每行一份文件,而不是一個陣列。要把它變成陣列,執行 jq -s . users.json > users-array.json。
  • 對應和陣列保持巢狀。每一行還有一個來自匯出的 __key__ 物件,裡面存放著文件 ID。
  • BigQuery 每個檔案最多寫入 1 GB。更多資料請使用萬用字元,例如 gs://YOUR_BUCKET/users-*.json。
  • 匯出依每份文件一次文件讀取計費。完成後刪除匯出資料夾,以免繼續佔用 Cloud Storage。

常見問題

Firebase 控制台能把 Firestore 資料匯出成 JSON 嗎?

不能。Realtime Database 的資料檢視器選單裡有「匯出 JSON」,但 Firestore 的「資料」分頁沒有下載功能。代管匯出(Google Cloud 控制台的匯入/匯出頁面,或 gcloud firestore export)會把 Firestore 自有格式的備份寫入 Cloud Storage,而不是 JSON。

為什麼 Firestore REST API 會回傳 {"stringValue": "..."} 這樣的值?

REST API 會把每個欄位包在它的型別裡:stringValue、integerValue、timestampValue、mapValue 等等。它是 JSON,但不是你文件本來的形狀。Admin SDK(方法 2)會替你解開這些型別。

可以把 JSON 匯回 Firestore 嗎?

不能直接匯回。gcloud firestore import 只讀取代管匯出,而這些 JSON 檔案都不是代管匯出。要載入 JSON 檔案,請用指令碼寫回去(Admin SDK 的 BulkWriter 能處理大批量寫入)。如果目標是還原資料,請使用代管匯出和匯入,而不是 JSON。

匯出 Firestore 資料要花錢嗎?

每種方法都會至少讀取一次每份匯出的文件,Firestore 會把這些計為文件讀取。在每日免費配額內不花錢。代管匯出還需要專案啟用計費,其檔案在刪除之前會一直佔用 Cloud Storage。