Database

How to Seed Firebase Firestore with Test Data

The Problem

Firebase Firestore has no seed command. When you start a new project or reset the emulator, you are left clicking through the console to add documents by hand, or writing verbose scripts that call doc().set() dozens of times with hardcoded values.

For document databases, the challenge is worse than SQL. You need nested objects, arrays of references, and subcollections, and Faker.js knows nothing about Firestore's data model.

The Solution: MockHero API

MockHero generates realistic data for any schema you define, including nested objects. Use ref fields to link collections and get back JSON ready to write to Firestore with the Admin SDK.

Quick Setup

curl -X POST https://api.mockhero.dev/api/v1/generate \
  -H "x-api-key: mh_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
  "tables": [
    {
      "name": "users",
      "count": 10,
      "fields": [
        { "name": "id", "type": "uuid" },
        { "name": "displayName", "type": "full_name" },
        { "name": "email", "type": "email" },
        { "name": "photoURL", "type": "avatar_url" },
        { "name": "createdAt", "type": "datetime" }
      ]
    },
    {
      "name": "messages",
      "count": 50,
      "fields": [
        { "name": "id", "type": "uuid" },
        { "name": "senderId", "type": "ref", "params": { "ref": "users.id" } },
        { "name": "text", "type": "sentence" },
        { "name": "sentAt", "type": "datetime" }
      ]
    }
  ],
  "format": "json"
}'

Step-by-Step Guide

1. Install dependencies

npm install firebase-admin

2. Get your MockHero API key

Sign up at mockhero.dev/sign-up and grab your key.

3. Write the seed script

Create seed.mjs:

import admin from "firebase-admin";

admin.initializeApp();
const db = admin.firestore();

const res = await fetch("https://api.mockhero.dev/api/v1/generate", {
  method: "POST",
  headers: {
    "x-api-key": process.env.MOCKHERO_API_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    tables: [
      {
        name: "users",
        count: 10,
        fields: [
          { name: "id", type: "uuid" },
          { name: "displayName", type: "full_name" },
          { name: "email", type: "email" },
          { name: "photoURL", type: "avatar_url" },
          { name: "createdAt", type: "datetime" },
        ],
      },
      {
        name: "messages",
        count: 50,
        fields: [
          { name: "id", type: "uuid" },
          { name: "senderId", type: "ref", params: { ref: "users.id" } },
          { name: "text", type: "sentence" },
          { name: "sentAt", type: "datetime" },
        ],
      },
    ],
    format: "json",
  }),
});

const { data } = await res.json();
const batch = db.batch();

for (const user of data.users) {
  batch.set(db.collection("users").doc(user.id), user);
}
for (const msg of data.messages) {
  batch.set(db.collection("messages").doc(msg.id), msg);
}

await batch.commit();
console.log("Seeded", data.users.length, "users and", data.messages.length, "messages");

4. Run it

GOOGLE_APPLICATION_CREDENTIALS=./service-account.json node seed.mjs

5. Verify in the Firebase console

Open your Firestore console and browse the users and messages collections. Every message's senderId references a real user document.

Complete Example

The script above is the complete solution. It uses Firestore batched writes for efficiency and MockHero's ref fields to maintain referential integrity across collections.

Why MockHero vs Faker / Manual Seeds

  • Batch-ready JSON — MockHero returns arrays you can loop through directly.
  • Emulator compatible — works identically against the Firestore emulator for local dev.
  • No Firestore-specific library — MockHero is database-agnostic, so you keep the same workflow if you migrate.

Get Started

Free tier, 1,000 rows/month, no credit card. Sign up at mockhero.dev and fill your Firestore in seconds.

M

MockHero Team

Guides and tutorials for generating realistic test data with the MockHero API.

Start generating test data for free

1,000 rows/month on the free tier. No credit card required.

Get Your API Key

Related Articles