FirexportAnleitungen
CSV und JSON in Firestore importieren
Die Firebase Console legt Firestore-Dokumente einzeln über Dokument hinzufügen (Add document) an und hat keinen Button, um eine Datei zu laden. Der eigene Import von Google, gcloud firestore import, liest nur die eigenen Exportdateien von Firestore, kein CSV oder JSON. Es gibt drei Wege, eine Datei in eine Sammlung zu bekommen. Welcher passt, hängt davon ab, wie groß die Datei ist und woher sie kommt.
Aktualisiert am 21. Oktober 2026. Firexport, die Erweiterung in Methode 1, ist von uns. Die Methoden 2 und 3 brauchen sie nicht.
Die kurze Antwort
- Eine CSV- oder JSON-Datei in eine Sammlung, jetzt sofort: in der Panelansicht (Panel view) der Console mit einer Browser-Erweiterung importieren. Methode 1
- Eine sehr große Datei, ein Job nach Zeitplan oder eigene Umwandlungen: ein kurzes Admin-SDK-Skript. Methode 2
- Eine ganze Datenbank aus einem anderen Projekt oder aus einer Sicherung: verwalteter Export und Import mit gcloud (liest kein CSV oder JSON). Methode 3
| 1. Console + Erweiterung | 2. Admin-SDK-Skript | 3. Verwalteter Import mit gcloud | |
|---|---|---|---|
| Einrichtung | Eine Chrome-Erweiterung installieren, Ihr Google-Konto verbinden | Node.js und Google-Cloud-Anmeldedaten | Ein Cloud-Storage-Bucket und gcloud |
| Liest | CSV, JSON, JSON Lines oder eingefügten Text | CSV, JSON, JSON Lines (was Ihr Code liest) | Nur die eigenen Exportdateien von Firestore |
| Feldtypen | Pro Feld gewählt, mit Vorschau | Was Ihr Code umwandelt | Aus dem Export übernommen |
| Vorhandene Dokumente | Belassen, ersetzen oder zusammenführen | Erstellen, ersetzen oder zusammenführen | Überschrieben |
| Abrechnung aktiviert | Nicht nötig | Nicht nötig | Erforderlich (Blaze-Tarif) |
1. Mit Firexport aus der Firebase Console importieren
Firexport ist eine kostenlose Chrome-Erweiterung, die der Panelansicht von Firestore ein Importsymbol hinzufügt: rechts am Ende der Zeile Dokument hinzufügen (Add document) jeder Sammlung. Es schreibt mit einem Google-Konto, das Sie verbinden – kein Dienstkontoschlüssel und kein Code einzurichten.
- Installieren Sie Firexport aus dem Chrome Web Store.
- Öffnen Sie in der Firebase Console Firestore Database > Daten (Data) in der Panelansicht (Panel view) und klicken Sie auf die Sammlung, in die Sie importieren möchten.
- Klicken Sie auf das Importsymbol rechts am Ende der Zeile Dokument hinzufügen (Add document).
- Wählen Sie eine CSV-, JSON- oder JSON-Lines-Datei aus oder ziehen Sie sie hinein – oder wechseln Sie zu Text einfügen und klicken Sie auf Lesen.
- Prüfen Sie den Typ jedes Felds und woher die Dokument-IDs kommen, und wählen Sie, was passiert, wenn ein Dokument schon existiert.
- Beim ersten Mal klicken Sie im Fenster auf Google-Konto verbinden, wählen das Konto, das in das Projekt schreiben darf, und erlauben den Zugriff im Fenster von Google. Klicken Sie dann auf Importieren.


Feldtypen und Dokument-IDs
- CSV-Zellen sind Text, und JSON kennt keine Zeitstempel oder Referenzen. Deshalb schlägt Firexport für jedes Feld anhand seiner Werte einen Typ vor: String, Ganzzahl, Zahl (double), Boolescher Wert, Zeitstempel, Referenz, Geopunkt oder Bytes (base64) – oder Nicht importieren. Es schlägt einen Typ nur vor, wenn jeder Wert passt, und Sie können jeden davon ändern.
- Zeitstempel können ISO 8601 (
2026-10-01T09:30:00Z),2026-10-01 09:30:00in der Zeitzone Ihres Browsers oder Millisekunden sein. Referenzen können ein Pfad wieusers/u1sein. Werte in Maps und Arrays behalten ihre JSON-Typen, verschachtelte Daten gehören also in JSON: Eine CSV-Spalte ist immer ein Feld der obersten Ebene. - Dokument-IDs kommen aus einer Spalte, die Sie wählen, aus den Schlüsseln eines JSON-Objekts, oder es werden neue zufällige IDs. Eine Spalte
Document IDwird automatisch gewählt, eine von Firexport exportierte Datei lässt sich also unverändert importieren. Als Pfad geschriebene IDs wie/users/u1verwenden ihr letztes Segment. - Eine Vorschau zeigt das erste Dokument so, wie es geschrieben wird, mit dem Typ jedes Werts. Zeilen, die sich nicht schreiben lassen – etwa ein Wert, der nicht zu seinem Typ passt, oder eine doppelte ID –, werden aufgelistet und weggelassen, bevor etwas gesendet wird.
Wenn ein Dokument schon existiert
Belassen, die Voreinstellung, erstellt nur neue Dokumente: Zeilen, deren ID schon existiert, schlagen fehl und werden aufgelistet. Ersetzen gibt dem Dokument genau die Felder aus der Datei. Zusammenführen schreibt die Felder aus der Datei, auch innerhalb von Maps, und behält die anderen Felder des Dokuments. Neue zufällige IDs treffen nie auf ein vorhandenes Dokument.

Jedes Dokument ist ein Firestore-Schreibvorgang, der dem Projekt berechnet wird. Firexport sendet bis zu 500 Schreibvorgänge pro Sekunde und wiederholt die, die aus einem vorübergehenden Grund fehlgeschlagen sind. Ist jede Zeile geschrieben, schließt sich das Fenster mit einem kurzen Hinweis; sind einige fehlgeschlagen, listet es sie auf, bietet einen CSV-Bericht an und kann fortsetzen. Die Schreibvorgänge nutzen die Berechtigungen des verbundenen Kontos, daher gelten die Sicherheitsregeln nicht. Ihre Datei geht von Ihrem Browser direkt zu Google und nie zu uns. Dateien und eingefügter Text dürfen bis zu 100 MB groß sein.
Importieren Sie eine CSV- oder JSON-Datei direkt aus der Console in Firestore – ohne Skript und ohne Dienstkontoschlüssel.
2. Mit einem Admin-SDK-Skript importieren
Für eine Datei über 100 MB, einen Import, der nach Zeitplan läuft, oder eigene Umwandlungen schreibt ein Node.js-Skript mit dem Firebase Admin SDK die Zeilen selbst. Das Skript unten liest eine CSV mit Kopfzeile, ein JSON-Array, ein JSON-Objekt mit Dokument-IDs als Schlüsseln oder JSON Lines und schreibt ein Dokument pro Zeile. Es braucht ein Konto, das in Firestore schreiben darf: einen Projekt-Inhaber oder -Bearbeiter oder die Rolle Cloud Datastore-Nutzer.
- SDK und einen CSV-Parser installieren:
npm install firebase-admin csv-parse - Für lokale Anmeldedaten anmelden:
gcloud auth application-default login. Auf einem Server lassen Sie stattdessenGOOGLE_APPLICATION_CREDENTIALSauf einen Dienstkontoschlüssel zeigen. - Speichern Sie das Skript unten als
import-to-firestore.mjs, ersetzen Sieyour-project-id, tragen Sie inTYPESIhre Felder ein und führen Sienode import-to-firestore.mjs orders.csv ordersaus.
// Usage: node import-to-firestore.mjs orders.csv orders → one document per row in orders
// Reads .csv (with a header row), .json (an array, or an object keyed by document ID) and .jsonl.
import { readFileSync } from 'node:fs';
import { initializeApp } from 'firebase-admin/app';
import { getFirestore, Timestamp } from 'firebase-admin/firestore';
import { parse } from 'csv-parse/sync';
initializeApp({ projectId: 'your-project-id' });
const db = getFirestore();
const [file, collection] = process.argv.slice(2);
if (!file || !collection) throw new Error('Usage: node import-to-firestore.mjs <file> <collection>');
// The column or key that holds each document's ID. Rows without one get a random ID.
const ID_FIELD = 'Document ID';
// CSV cells are all text and JSON has no timestamps: list the fields to convert. The rest stay as they are.
const TYPES = { createdAt: 'timestamp', items: 'integer', total: 'number' };
// 'create' never touches an existing document (that row fails), 'set' replaces it, 'merge' adds to it.
const MODE = 'create';
const text = readFileSync(file, 'utf8');
const isCsv = file.endsWith('.csv');
let rows;
if (isCsv) {
rows = parse(text, { columns: true, bom: true, skip_empty_lines: true });
} else if (file.endsWith('.jsonl')) {
rows = text.split('\n').filter((line) => line.trim()).map((line) => JSON.parse(line));
} else {
const json = JSON.parse(text);
rows = Array.isArray(json) ? json : Object.entries(json).map(([id, data]) => ({ [ID_FIELD]: id, ...data }));
}
function convert(type, value) {
if (type === 'timestamp') {
const date = new Date(/^\d+$/.test(value) ? Number(value) : value); // ISO 8601 or milliseconds
if (Number.isNaN(date.getTime())) throw new Error(`not a timestamp: ${value}`);
return Timestamp.fromDate(date);
}
if (type === 'integer' || type === 'number') {
const number = Number(value);
if (value === '' || !Number.isFinite(number) || (type === 'integer' && !Number.isInteger(number))) {
throw new Error(`not ${type === 'integer' ? 'an integer' : 'a number'}: ${value}`);
}
return number;
}
if (type === 'boolean') return value === true || value === 'true';
return value;
}
// Convert every row before writing anything, so a bad value stops the import instead of half of it.
const docs = rows.map((row, index) => {
const data = {};
for (const [field, value] of Object.entries(row)) {
if (field === ID_FIELD || (isCsv && value === '')) continue; // an empty CSV cell is a missing field
try {
data[field] = TYPES[field] ? convert(TYPES[field], value) : value;
} catch (error) {
throw new Error(`Row ${index + 1}, ${field}: ${error.message}`);
}
}
const id = row[ID_FIELD] ? String(row[ID_FIELD]).split('/').pop() : undefined; // a path keeps its last part
return { row: index + 1, ref: id ? db.collection(collection).doc(id) : db.collection(collection).doc(), data };
});
// BulkWriter sends the writes in batches, keeps under Firestore's rate limits and retries what can be retried.
const writer = db.bulkWriter();
const failures = [];
for (const { row, ref, data } of docs) {
const write = MODE === 'create' ? writer.create(ref, data) : writer.set(ref, data, { merge: MODE === 'merge' });
write.catch((error) => failures.push(`Row ${row} (${ref.id}): ${error.message}`));
}
await writer.close();
console.log(`Wrote ${docs.length - failures.length} of ${docs.length} documents to ${collection}`);
failures.forEach((failure) => console.log(failure));- CSV-Zellen sind Text: Das Skript wandelt nur die in
TYPESaufgeführten Felder um und behält den Rest als Strings. Eine leere Zelle wird zu einem fehlenden Feld. JSON-Werte behalten ihre Typen, und Maps und Arrays werden unverändert geschrieben – außer einem Array direkt in einem anderen Array, das Firestore ablehnt. - Jede Zeile wird umgewandelt, bevor etwas geschrieben wird. Ein ungültiger Wert hält das Skript also mit seiner Zeile und seinem Feld an, statt einen halben Import zu hinterlassen.
- Ist
MODEauf'create'gesetzt, bleiben vorhandene Dokumente unberührt, und ihre Zeilen werden als fehlgeschlagen aufgelistet.'set'ersetzt sie, und'merge'fügt die Felder der Datei hinzu. Zeilen ohne ID bekommen bei jedem Lauf eine neue zufällige ID: Führen Sie das Skript zweimal aus, werden sie also doppelt angelegt. BulkWriterbündelt die Schreibvorgänge, beginnt mit 500 pro Sekunde, steigert sich, so weit die 500/50/5-Regel von Firestore es erlaubt, und wiederholt Schreibvorgänge, die aus einem vorübergehenden Grund fehlgeschlagen sind. Die Sammlung kann ein Untersammlungspfad sein, etwausers/u1/orders. Wie Methode 1 umgeht es die Sicherheitsregeln, und jedes Dokument ist ein Schreibvorgang.
3. Eine ganze Datenbank mit dem verwalteten Import von gcloud kopieren
gcloud firestore import, auch über die Seite Import/Export von Firestore in der Google Cloud Console erreichbar, ist der verwaltete Import von Firestore. Er liest nur, was gcloud firestore export im eigenen Format von Firestore in einen Cloud-Storage-Bucket geschrieben hat, kein CSV oder JSON. Nutzen Sie ihn, um eine Sicherung wiederherzustellen oder um Sammlungen samt ihren Typen aus einem Projekt oder einer Datenbank in ein anderes Projekt oder eine andere Datenbank zu kopieren.
# 1. Export the collection from the source project.
gcloud firestore export gs://YOUR_BUCKET/orders-export --collection-ids=orders --project=source-project-id
# 2. Import that export into the destination project.
gcloud firestore import gs://YOUR_BUCKET/orders-export --project=destination-project-id- Die Abrechnung muss aktiviert sein (Blaze-Tarif). Der Import ist ein Schreibvorgang pro Dokument.
- Ein Import überschreibt Dokumente mit derselben ID und lässt die anderen Dokumente stehen. Er löst keine Cloud Functions aus.
- Ihr Konto braucht die Rolle Inhaber, Cloud Datastore-Inhaber oder Cloud Datastore-Import-/Export-Administrator. Um aus dem Bucket eines anderen Projekts zu importieren, braucht der Firestore-Dienst-Agent des Zielprojekts,
service-PROJECT_NUMBER@gcp-sa-firestore.iam.gserviceaccount.com, Zugriff auf diesen Bucket.
FAQ
Kann die Firebase Console eine CSV- oder JSON-Datei in Firestore importieren?
Nein. Der Tab „Daten“ von Firestore legt Dokumente einzeln über Dokument hinzufügen (Add document) an, und gcloud firestore import liest nur die eigenen Exportdateien von Firestore. Um eine CSV- oder JSON-Datei zu laden, braucht es ein Admin-SDK-Skript oder eine Browser-Erweiterung wie Firexport, die der Console einen Import hinzufügt.
Wie importiere ich eine JSON-Datei in Firestore?
Nutzen Sie ein JSON-Array von Objekten, eines pro Dokument, oder ein Objekt mit Dokument-IDs als Schlüsseln. In Firexport klicken Sie auf das Importsymbol in der Zeile Dokument hinzufügen (Add document) der Sammlung und wählen die Datei; Maps und Arrays behalten ihre JSON-Typen. Mit dem Admin SDK lesen Sie die Datei und schreiben jedes Objekt mit BulkWriter, wie im Skript oben.
Wie werden Zeitstempel und Referenzen importiert?
CSV und JSON können keine Firestore-Typen tragen, ein Zeitstempel in einer Datei ist also nur Text, bis etwas ihn umwandelt. Firexport wandelt ihn um, wenn Sie den Typ des Felds auf Zeitstempel, Referenz oder Geopunkt setzen. In einem Skript wandeln Sie ihn selbst um, zum Beispiel mit Timestamp.fromDate(new Date(value)) oder db.doc(path).
Gelten die Sicherheitsregeln bei einem Import?
Nein. Der Import von Firexport, das Admin SDK und gcloud schreiben alle mit den IAM-Berechtigungen eines Kontos, und Sicherheitsregeln gelten nur für die Client-SDKs. Prüfen Sie die Daten und das Konto, bevor Sie importieren.
Was kostet ein Import in Firestore?
Jedes importierte Dokument ist ein Schreibvorgang, egal mit welcher Methode. Im kostenlosen Spark-Tarif geht das von den 20.000 Schreibvorgängen pro Tag ab, und Schreibvorgänge darüber hinaus schlagen fehl, bis das Kontingent zurückgesetzt wird. Im Blaze-Tarif werden Schreibvorgänge über das kostenlose Kontingent hinaus zum Preis des Standorts Ihrer Datenbank abgerechnet.
