Chapter 07 · Firebase Data Connect
Subchapter 7.3
reference/data_seeding.mdMarkdown6 KBView on GitHub
Use this reference to populate local development databases for prototyping, execute CI/CD tests, and perform bulk data migrations in production environments.
Local database seeding allows developer agents to test queries, mutations, complex joins, and role-based access control (RBAC) under realistic conditions.
Always write prototyping seed mutations to dataconnect/seed_data.gql
(located at the project root, not inside connector/). This file is excluded
from production deployments and client SDK generation.
Do not declare @auth directives inside seed_data.gql mutations. Since
this file runs locally to establish a test state and is not an exposed API
connector endpoint, authorization directives are completely unnecessary and
should be omitted.
When executing standard bulk insertions (_insertMany) across multiple tables,
always insert parent tables before referencing them in child or join tables.
# dataconnect/seed_data.gql
mutation SeedIndependentTables @transaction {
# Step 1: Seed parent tables
movie_insertMany(data: [
{ id: "m-1", title: "Inception", genre: "sci-fi" },
{ id: "m-2", title: "The Matrix", genre: "action" }
])
actor_insertMany(data: [
{ id: "a-1", name: "Leonardo DiCaprio" },
{ id: "a-2", name: "Keanu Reeves" }
])
# Step 2: Seed join table (depends on pre-existing parent IDs)
movieActor_insertMany(data: [
{ movie: { id: "m-1" }, actor: { id: "a-1" }, role: "main" },
{ movie: { id: "m-2" }, actor: { id: "a-2" }, role: "main" }
])
}To seed parent-child relationships atomically, perform a nested relational insert using literal payloads. This avoids the need to manage foreign keys manually.
movieId) inside the nested child objects. The database engine automatically
maps and resolves them.# dataconnect/seed_data.gql
mutation SeedMoviesAndReviews @transaction {
movie_insert(data: {
id: "m-1",
title: "Inception",
genre: "sci-fi",
# Nested reviews are inserted atomically without manual movieId mapping
reviews_on_movie: [
{
id: "r-1",
rating: 5,
reviewText: "Mind-bending masterpiece!",
user: { id: "user-123" } # Links to pre-existing user
},
{
id: "r-2",
rating: 4,
reviewText: "Visually stunning but complex.",
user: { id: "user-456" }
}
]
})
}For continuous testing or CI/CD flows, return the database to a zero state using one of the following strategies:
_upsertMany
mutations. This overrides existing records or inserts missing ones in a single
step._deleteMany(all: true) on your
tables in reverse foreign key order (child/join tables first, then parent
tables) followed by your seed _insertMany operations.# dataconnect/seed_data.gql
mutation ResetDatabaseToOriginalState @transaction {
# Delete child tables first to prevent FK constraint violations
movieActor_deleteMany(all: true)
actor_deleteMany(all: true)
movie_deleteMany(all: true)
# (Optional) Follow up with new _insertMany steps
}Use the Firebase Admin SDK for Node.js for bulk data loading and production migrations. Avoid running large mutations directly via raw GraphQL endpoints in production.
The Admin SDK provides direct, type-safe methods: dc.insert, dc.insertMany,
dc.upsert, and dc.upsertMany.
mutation {...} strings when
executing privileged batch operations. Pass Javascript objects directly.import { initializeApp } from 'firebase-admin/app';
import { getDataConnect } from 'firebase-admin/data-connect';
const app = initializeApp();
const dc = getDataConnect({ location: "us-west2", serviceId: "my-service" });
const bulkMoviesData = [
{
id: "m-1",
title: "Inception",
genre: "sci-fi",
// Atomic nested relational inserts are fully supported
reviews_on_movie: [
{
rating: 5,
reviewText: "Incredible concept.",
user: { id: "user-123" }
}
]
},
{
id: "m-2",
title: "The Matrix",
genre: "action",
reviews_on_movie: [
{
rating: 5,
reviewText: "A classic.",
user: { id: "user-456" }
}
]
}
];
// Atomically load thousands of records (parent and child tables combined)
const response = await dc.insertMany("movie", bulkMoviesData);When working with a stable schema in production, you can use standard SQL tools
(like psql or Cloud SQL import pipelines) to execute bulk data updates
directly on the PostgreSQL instance.
Never modify your database schema directly using SQL tools. Direct schema
alterations (ALTER TABLE, CREATE INDEX, etc.) outside of your schema.gql
file will bypass SQL Connect’s schema compiler, breaking connector mappings, and
causing active client SDK integrations to fail.