FirexportGuías
Cómo importar CSV y JSON a Firestore
Firebase console agrega documentos de Firestore de uno en uno, con Agregar documento (Add document), y no tiene ningún botón para cargar un archivo. La importación propia de Google, gcloud firestore import, solo lee los archivos de exportación propios de Firestore, no CSV ni JSON. Hay tres formas de cargar un archivo en una colección. Cuál te conviene depende del tamaño del archivo y de dónde venga.
Actualizado el 21 de octubre de 2026. Firexport, la extensión del método 1, es nuestra. Los métodos 2 y 3 no la necesitan.
La respuesta corta
- Un archivo CSV o JSON en una colección, ahora mismo: impórtalo desde la vista de panel (Panel view) de la consola con una extensión del navegador. Método 1
- Un archivo muy grande, una tarea programada o conversiones a tu manera: un script corto con el Admin SDK. Método 2
- Una base de datos entera desde otro proyecto o una copia de seguridad: exportación e importación administradas con gcloud (no lee CSV ni JSON). Método 3
| 1. Consola + extensión | 2. Script con Admin SDK | 3. Importación administrada con gcloud | |
|---|---|---|---|
| Configuración | Instalar una extensión de Chrome, conectar tu cuenta de Google | Node.js y credenciales de Google Cloud | Un bucket de Cloud Storage y gcloud |
| Lee | CSV, JSON, JSON Lines o texto pegado | CSV, JSON, JSON Lines (lo que lea tu código) | Solo los archivos de exportación propios de Firestore |
| Tipos de campo | Elegidos por campo, con vista previa | Lo que convierta tu código | Se conservan de la exportación |
| Documentos existentes | Dejar, reemplazar o combinar | Crear, reemplazar o combinar | Se sobrescriben |
| Facturación habilitada | No hace falta | No hace falta | Obligatoria (plan Blaze) |
1. Importar desde Firebase console con Firexport
Firexport es una extensión gratuita de Chrome que agrega un ícono de importar a la vista de panel (Panel view) de Firestore, en el extremo derecho de la fila Agregar documento (Add document) de cada colección. Escribe con una cuenta de Google que tú conectas, así que no hay que configurar ninguna clave de cuenta de servicio ni código.
- Instala Firexport desde Chrome Web Store.
- En Firebase console, abre Firestore Database > Datos (Data) en vista de panel (Panel view) y haz clic en la colección a la que quieres importar.
- Haz clic en el ícono de importar, en el extremo derecho de la fila Agregar documento (Add document).
- Elige o suelta un archivo CSV, JSON o JSON Lines, o cambia a Pegar texto y haz clic en Leer.
- Revisa el tipo de cada campo y de dónde salen los ID de los documentos, y elige qué pasa si un documento ya existe.
- La primera vez, la ventana te pide Conectar cuenta de Google: elige la cuenta que puede escribir en el proyecto y permite el acceso en la ventana de Google. Luego haz clic en Importar.


Tipos de campo e ID de los documentos
- Las celdas de un CSV son texto, y JSON no tiene marcas de tiempo ni referencias. Por eso Firexport sugiere un tipo para cada campo a partir de sus valores: Cadena, Entero, Número (double), Booleano, Marca de tiempo, Referencia, Punto geográfico o Bytes (base64), o No importar. Solo sugiere uno cuando todos los valores encajan, y puedes cambiar cualquiera.
- Las marcas de tiempo pueden ser ISO 8601 (
2026-10-01T09:30:00Z),2026-10-01 09:30:00en la zona horaria de tu navegador, o milisegundos. Las referencias pueden ser una ruta comousers/u1. Los valores dentro de mapas y arreglos conservan sus tipos JSON, así que los datos anidados van en JSON: una columna de CSV siempre es un campo de nivel superior. - Los ID de los documentos salen de una columna que eliges, de las claves de un objeto JSON, o son ID aleatorios nuevos. Una columna
Document IDse elige automáticamente, así que un archivo que exportó Firexport se importa tal cual. Los ID escritos como rutas, como/users/u1, usan su último segmento. - Una vista previa muestra el primer documento tal como se escribirá, con el tipo de cada valor. Las filas que no se pueden escribir, como un valor que no corresponde a su tipo o un ID repetido, se muestran en una lista y se dejan fuera antes de enviar nada.
Cuando un documento ya existe
Dejarlo, la opción predeterminada, solo crea documentos nuevos: las filas cuyo ID ya existe fallan y se muestran en la lista. Reemplazarlo deja el documento exactamente con los campos del archivo. Combinarlo escribe los campos del archivo, incluso dentro de mapas, y conserva los otros campos del documento. Los ID aleatorios nuevos nunca coinciden con un documento existente.

Cada documento es una escritura de Firestore que se factura al proyecto. Firexport envía hasta 500 escrituras por segundo y reintenta las que fallaron por un motivo temporal. Cuando se escriben todas las filas, la ventana se cierra con un aviso breve; si algunas fallaron, las muestra en una lista, ofrece un informe CSV y puede reanudar. Las escrituras usan los permisos de la cuenta conectada, así que las reglas de seguridad no se aplican. Tu archivo va de tu navegador directamente a Google, y nunca a nosotros. Los archivos y el texto pegado pueden tener hasta 100 MB.
Importa un archivo CSV o JSON a Firestore desde la consola, sin scripts ni claves de cuenta de servicio.
2. Importar con un script del Admin SDK
Para un archivo de más de 100 MB, una importación que se ejecute de forma programada o conversiones a tu manera, un script de Node.js con el Firebase Admin SDK escribe las filas por sí mismo. El de abajo lee un CSV con fila de encabezado, un arreglo JSON, un objeto JSON con el ID del documento como clave, o JSON Lines, y escribe un documento por fila. Necesita una cuenta que pueda escribir en Firestore: un Propietario o Editor del proyecto, o el rol Usuario de Cloud Datastore.
- Instala el SDK y un analizador de CSV:
npm install firebase-admin csv-parse - Inicia sesión para obtener credenciales locales:
gcloud auth application-default login. En un servidor, apuntaGOOGLE_APPLICATION_CREDENTIALSa una clave de cuenta de servicio. - Guarda el script de abajo como
import-to-firestore.mjs, reemplazayour-project-id, ajustaTYPESa tus campos y ejecutanode import-to-firestore.mjs orders.csv orders.
// 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));- Las celdas de un CSV son texto: el script convierte solo los campos que aparecen en
TYPESy deja el resto como cadenas. Una celda vacía se convierte en un campo ausente. Los valores JSON conservan sus tipos, y los mapas y arreglos se escriben tal cual, salvo un arreglo directamente dentro de otro arreglo, que Firestore rechaza. - Todas las filas se convierten antes de escribir nada, así que un valor incorrecto detiene el script con su fila y su campo en lugar de dejar media importación.
- Con
MODEen'create', los documentos existentes no se tocan y sus filas aparecen como fallidas.'set'los reemplaza y'merge'agrega los campos del archivo. Las filas sin ID reciben un ID aleatorio nuevo en cada ejecución, así que ejecutar el script dos veces las duplica. BulkWriteragrupa las escrituras en lotes, empieza con 500 por segundo y va subiendo según lo permite la regla 500/50/5 de Firestore, y reintenta las escrituras que fallaron por un motivo temporal. La colección puede ser la ruta de una subcolección, comousers/u1/orders. Igual que el método 1, no pasa por las reglas de seguridad, y cada documento es una escritura.
3. Copiar una base de datos entera con la importación administrada de gcloud
gcloud firestore import, también disponible en la página Importar/Exportar de Firestore en la consola de Google Cloud, es la importación administrada de Firestore. Solo lee lo que gcloud firestore export escribió en un bucket de Cloud Storage, en el formato propio de Firestore, no CSV ni JSON. Úsala para restaurar una copia de seguridad, o para copiar colecciones de un proyecto o base de datos a otro con sus tipos intactos.
# 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- La facturación debe estar habilitada (el plan Blaze). La importación es una escritura por documento.
- Una importación sobrescribe los documentos con el mismo ID y deja los demás documentos como están. No activa Cloud Functions.
- Tu cuenta necesita el rol Propietario, Propietario de Cloud Datastore o Administrador de importación y exportación de Cloud Datastore. Para importar desde el bucket de otro proyecto, el agente de servicio de Firestore del proyecto de destino,
service-PROJECT_NUMBER@gcp-sa-firestore.iam.gserviceaccount.com, necesita acceso a ese bucket.
Preguntas frecuentes
¿Puede Firebase console importar un archivo CSV o JSON a Firestore?
No. La pestaña Datos de Firestore agrega documentos de uno en uno con Agregar documento (Add document), y gcloud firestore import solo lee los archivos de exportación propios de Firestore. Para cargar un archivo CSV o JSON hace falta un script del Admin SDK, o una extensión del navegador como Firexport que agregue una importación a la consola.
¿Cómo importo un archivo JSON a Firestore?
Usa un arreglo JSON de objetos, uno por documento, o un objeto con el ID del documento como clave. En Firexport, haz clic en el ícono de importar de la fila Agregar documento (Add document) de la colección y elige el archivo; los mapas y arreglos conservan sus tipos JSON. Con el Admin SDK, lee el archivo y escribe cada objeto con BulkWriter, como en el script de arriba.
¿Cómo se importan las marcas de tiempo y las referencias?
CSV y JSON no pueden llevar tipos de Firestore, así que una marca de tiempo en un archivo es solo texto hasta que algo la convierta. Firexport la convierte cuando pones el tipo del campo en Marca de tiempo, Referencia o Punto geográfico. En un script, conviértela tú, por ejemplo con Timestamp.fromDate(new Date(value)) o db.doc(path).
¿Se aplican las reglas de seguridad a una importación?
No. La importación de Firexport, el Admin SDK y gcloud escriben con los permisos de IAM de una cuenta, y las reglas de seguridad solo se aplican a los SDK de cliente. Revisa los datos, y la cuenta, antes de importar.
¿Cuánto cuesta importar a Firestore?
Cada documento importado es una escritura, uses el método que uses. En el plan gratuito Spark eso sale de las 20.000 escrituras diarias, y las escrituras que pasen de ahí fallan hasta que se restablezca la cuota. En Blaze, las escrituras por encima del nivel gratuito se facturan a la tarifa de la ubicación de tu base de datos.
