FirexportGuias
Como importar CSV e JSON para o Firestore
O Console do Firebase adiciona documentos do Firestore um de cada vez, com Adicionar documento (Add document), e não tem botão para carregar um arquivo. A importação do próprio Google, gcloud firestore import, só lê os arquivos de exportação do próprio Firestore, não CSV nem JSON. Há três formas de colocar um arquivo em uma coleção. Qual delas serve depende do tamanho do arquivo e de onde ele vem.
Atualizado em 21 de outubro de 2026. O Firexport, a extensão do método 1, é nosso. Os métodos 2 e 3 não precisam dele.
A resposta curta
- Um arquivo CSV ou JSON em uma coleção, agora: importe-o da visualização em painel (Panel view) do console com uma extensão do navegador. Método 1
- Um arquivo muito grande, uma tarefa agendada ou conversões do seu jeito: um script curto com o Admin SDK. Método 2
- Um banco de dados inteiro de outro projeto ou de um backup: exportação e importação gerenciadas com gcloud (não lê CSV nem JSON). Método 3
| 1. Console + extensão | 2. Script com Admin SDK | 3. Importação gerenciada com gcloud | |
|---|---|---|---|
| Configuração | Instalar uma extensão do Chrome, conectar sua conta do Google | Node.js e credenciais do Google Cloud | Um bucket do Cloud Storage e o gcloud |
| Lê | CSV, JSON, JSON Lines ou texto colado | CSV, JSON, JSON Lines (o que seu código ler) | Só os arquivos de exportação do próprio Firestore |
| Tipos de campo | Escolhidos por campo, com uma prévia | O que seu código converter | Mantidos da exportação |
| Documentos existentes | Manter, substituir ou mesclar | Criar, substituir ou mesclar | Sobrescritos |
| Faturamento ativado | Não precisa | Não precisa | Obrigatório (plano Blaze) |
1. Importar do Console do Firebase com o Firexport
O Firexport é uma extensão gratuita do Chrome que adiciona um ícone de importação à visualização em painel (Panel view) do Firestore, na ponta direita da linha Adicionar documento (Add document) de cada coleção. Ele grava com uma conta do Google que você conecta, então não há chave de conta de serviço nem código para configurar.
- Instale o Firexport pela Chrome Web Store.
- No Console do Firebase, abra Firestore Database > Dados (Data) na visualização em painel (Panel view) e clique na coleção para a qual vai importar.
- Clique no ícone de importação na ponta direita da linha Adicionar documento (Add document).
- Escolha ou solte um arquivo CSV, JSON ou JSON Lines, ou mude para Colar texto e clique em Ler.
- Confira o tipo de cada campo e de onde vêm os IDs dos documentos, e escolha o que acontece se um documento já existir.
- Na primeira vez, a janela pede que você clique em Conectar conta do Google: escolha a conta que pode gravar no projeto e permita o acesso na janela do Google. Depois clique em Importar.


Tipos de campo e IDs de documentos
- As células de um CSV são texto, e o JSON não tem timestamps nem referências. Por isso o Firexport sugere um tipo para cada campo a partir dos valores dele: String, Inteiro, Número (double), Booleano, Carimbo de data/hora, Referência, Ponto geográfico ou Bytes (base64), ou Não importar. Ele só sugere um tipo quando todos os valores se encaixam nele, e você pode mudar qualquer um.
- Timestamps podem ser ISO 8601 (
2026-10-01T09:30:00Z),2026-10-01 09:30:00no fuso horário do seu navegador ou milissegundos. Referências podem ser um caminho comousers/u1. Valores dentro de mapas e arrays mantêm seus tipos JSON, então dados aninhados vão em JSON: uma coluna de CSV é sempre um campo de nível superior. - Os IDs dos documentos vêm de uma coluna que você escolhe, das chaves de um objeto JSON, ou são novos IDs aleatórios. Uma coluna
Document IDé escolhida automaticamente, então um arquivo que o Firexport exportou é importado como está. IDs escritos como caminhos, como/users/u1, usam o último segmento. - Uma prévia mostra o primeiro documento como ele será gravado, com o tipo de cada valor. Linhas que não podem ser gravadas, como um valor que não corresponde ao seu tipo ou um ID repetido, são listadas e ficam de fora antes que qualquer coisa seja enviada.
Quando um documento já existe
Manter, o padrão, só cria documentos novos: linhas cujo ID já existe falham e são listadas. Substituir deixa o documento exatamente com os campos do arquivo. Mesclar grava os campos do arquivo, inclusive dentro de mapas, e mantém os outros campos do documento. Novos IDs aleatórios nunca coincidem com um documento existente.

Cada documento é uma gravação do Firestore, cobrada do projeto. O Firexport envia até 500 gravações por segundo e tenta de novo as que falharam por um motivo temporário. Quando todas as linhas são gravadas, a janela se fecha com um aviso curto; se algumas falharem, ela as lista, oferece um relatório em CSV e pode retomar. As gravações usam as permissões da conta conectada, então as regras de segurança não se aplicam. Seu arquivo vai do seu navegador direto para o Google, e nunca para nós. Arquivos e texto colado podem ter até 100 MB.
Importe um arquivo CSV ou JSON para o Firestore direto do console, sem script nem chave de conta de serviço.
2. Importar com um script do Admin SDK
Para um arquivo com mais de 100 MB, uma importação que rode de forma agendada ou conversões do seu jeito, um script em Node.js com o Firebase Admin SDK grava as linhas por conta própria. O script abaixo lê um CSV com linha de cabeçalho, um array JSON, um objeto JSON com o ID do documento como chave ou JSON Lines, e grava um documento por linha. Ele precisa de uma conta que possa gravar no Firestore: um Proprietário ou Editor do projeto, ou o papel Usuário do Cloud Datastore.
- Instale o SDK e um parser de CSV:
npm install firebase-admin csv-parse - Faça login para obter credenciais locais:
gcloud auth application-default login. Em um servidor, aponteGOOGLE_APPLICATION_CREDENTIALSpara uma chave de conta de serviço. - Salve o script abaixo como
import-to-firestore.mjs, substituayour-project-id, definaTYPEScom os seus campos e executenode 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));- As células de um CSV são texto: o script converte só os campos listados em
TYPESe mantém o resto como strings. Uma célula vazia vira um campo ausente. Valores JSON mantêm seus tipos, e mapas e arrays são gravados como estão, exceto um array diretamente dentro de outro array, que o Firestore rejeita. - Todas as linhas são convertidas antes de qualquer gravação, então um valor inválido interrompe o script indicando a linha e o campo, em vez de deixar uma importação pela metade.
- Com
MODEdefinido como'create', os documentos existentes ficam como estão e suas linhas são listadas como falhas.'set'os substitui e'merge'adiciona os campos do arquivo. Linhas sem ID recebem um novo ID aleatório a cada execução, então executar o script duas vezes as duplica. - O
BulkWriteragrupa as gravações em lotes, começa com 500 por segundo e acelera conforme a regra 500/50/5 do Firestore permite, e tenta de novo as gravações que falharam por um motivo temporário. A coleção pode ser o caminho de uma subcoleção, comousers/u1/orders. Como o método 1, ele ignora as regras de segurança, e cada documento é uma gravação.
3. Copiar um banco de dados inteiro com a importação gerenciada do gcloud
O gcloud firestore import, também disponível na página Importar/Exportar do Firestore no console do Google Cloud, é a importação gerenciada do Firestore. Ele só lê o que o gcloud firestore export gravou em um bucket do Cloud Storage, no formato próprio do Firestore, não CSV nem JSON. Use-o para restaurar um backup, ou para copiar coleções de um projeto ou banco de dados para outro com os 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- O faturamento precisa estar ativado (plano Blaze). A importação é uma gravação por documento.
- Uma importação sobrescreve os documentos com o mesmo ID e deixa os outros documentos como estão. Ela não aciona o Cloud Functions.
- Sua conta precisa do papel Proprietário, Proprietário do Cloud Datastore ou Administrador de importação e exportação do Cloud Datastore. Para importar do bucket de outro projeto, o agente de serviço do Firestore do projeto de destino,
service-PROJECT_NUMBER@gcp-sa-firestore.iam.gserviceaccount.com, precisa de acesso a esse bucket.
Perguntas frequentes
O Console do Firebase consegue importar um arquivo CSV ou JSON para o Firestore?
Não. A guia Dados (Data) do Firestore adiciona documentos um de cada vez com Adicionar documento (Add document), e o gcloud firestore import só lê os arquivos de exportação do próprio Firestore. Para carregar um arquivo CSV ou JSON, é preciso um script do Admin SDK ou uma extensão do navegador, como o Firexport, que adicione uma importação ao console.
Como importo um arquivo JSON para o Firestore?
Use um array JSON de objetos, um por documento, ou um objeto com o ID do documento como chave. No Firexport, clique no ícone de importação na linha Adicionar documento (Add document) da coleção e escolha o arquivo; mapas e arrays mantêm seus tipos JSON. Com o Admin SDK, leia o arquivo e grave cada objeto com o BulkWriter, como no script acima.
Como timestamps e referências são importados?
CSV e JSON não carregam os tipos do Firestore, então um timestamp em um arquivo é só texto até que algo o converta. O Firexport o converte quando você define o tipo do campo como Carimbo de data/hora, Referência ou Ponto geográfico. Em um script, converta você mesmo, por exemplo com Timestamp.fromDate(new Date(value)) ou db.doc(path).
As regras de segurança se aplicam a uma importação?
Não. A importação do Firexport, o Admin SDK e o gcloud gravam todos com as permissões do IAM de uma conta, e as regras de segurança só se aplicam aos SDKs de cliente. Confira os dados, e a conta, antes de importar.
Quanto custa importar para o Firestore?
Cada documento importado é uma gravação, seja qual for o método. No plano Spark gratuito, isso sai das 20.000 gravações por dia, e as gravações além disso falham até a cota ser renovada. No Blaze, as gravações além do nível gratuito são cobradas pela tarifa do local do seu banco de dados.
