MSR: Firebase

Database migrations for Firebase Realtime Database with full TypeScript support.

Get started now View on GitHub


MSR

Part of the MSR Ecosystem

Powered by MSR Core v0.8.1

MSR Firebase is part of the Migration Script Runner family - a suite of database-specific migration tools built on a proven, battle-tested core. Inherits enterprise features like migration locking for distributed deployments, checksum validation, multiple rollback strategies, and comprehensive logging. Firebase-specific features and optimizations added on top.

Learn about MSR Core β†’

⚠️ Unstable Version: Version v0.2.0 is currently unstable and not recommended for production use. The project is under active development and may receive significant updates. Please use with caution and test thoroughly before deploying to production environments.


MSR Firebase provides a complete migration solution for Firebase Realtime Database, built on top of Migration Script Runner Core.

Quick Installation

npm install @migration-script-runner/firebase

Key Features

πŸ”’

Migration Locking

Production ready

Perfect for Kubernetes, Docker, and multi-instance deployments. Prevents race conditions with automatic lock expiration and force-release commands.

πŸ’Ύ

Backup & Restore

Automatic protection

Automatic backups before migrations with flexible restore options. Protect your data with multiple backup modes and point-in-time recovery.

πŸ”₯

Firebase Native

Optimized for Firebase

Built specifically for Firebase Realtime Database with support for single-node transactions, path prefixing, and full Firebase Admin SDK features.

πŸ›‘οΈ

Type-Safe Migrations

Full TypeScript support

First-class TypeScript support with full type definitions. Write migrations with confidence using generic type parameters and interfaces.

πŸ§ͺ

Emulator Support

Test before deploy

Test migrations locally with Firebase Emulator before deploying to production. Complete integration test support with isolated environments.

πŸ“¦

CLI & Library

Use your way

Use as a command-line tool for quick migrations or integrate programmatically into your Node.js application. Same powerful features, your choice.

β†’ View all features - Complete feature list with detailed descriptions

Important: Firebase Realtime Database does NOT support database-wide transactions. Unlike SQL databases or MongoDB, Firebase only supports atomic operations on a single node. This is a Firebase platform limitation, not an MSR Firebase limitation. See the Transaction Guide for safe migration patterns and workarounds.


Quick Example

1. Setup Credentials

You can provide Firebase credentials in two ways:

Option A: CLI Flags (Recommended for quick start)

npx msr-firebase migrate \
  --database-url https://your-project.firebaseio.com \
  --credentials ./serviceAccountKey.json

Option B: Environment Variables

# .env
DATABASE_URL=https://your-project.firebaseio.com
GOOGLE_APPLICATION_CREDENTIALS=./serviceAccountKey.json

2. Write a Migration

Create migrations as TypeScript classes with full type safety:

Real Example: This pattern is used in our integration tests and verified in production.

// migrations/V202501010001_create_users.ts
import { IRunnableScript, IMigrationInfo } from '@migration-script-runner/core';
import { IFirebaseDB, FirebaseHandler } from '@migration-script-runner/firebase';

export default class CreateUsers implements IRunnableScript<IFirebaseDB> {
  async up(
    db: IFirebaseDB,
    info: IMigrationInfo,
    handler: FirebaseHandler
  ): Promise<string> {
    // Access database with full type safety
    const usersRef = db.database.ref(handler.cfg.buildPath('users'));

    await usersRef.set({
      user1: { name: 'Alice', email: 'alice@example.com', role: 'admin' },
      user2: { name: 'Bob', email: 'bob@example.com', role: 'user' }
    });

    return 'Created users table with 2 initial users';
  }

  async down(
    db: IFirebaseDB,
    info: IMigrationInfo,
    handler: FirebaseHandler
  ): Promise<string> {
    await db.database.ref(handler.cfg.buildPath('users')).remove();
    return 'Removed users table';
  }
}

Advanced: Using EntityService for type-safe entity operations

See smoke tests for a complete workflow example running these migrations.

// migrations/V202501010002_add_posts.ts
import { IRunnableScript, IMigrationInfo } from '@migration-script-runner/core';
import { IFirebaseDB, FirebaseHandler, EntityService } from '@migration-script-runner/firebase';

interface Post {
  key?: string;
  title: string;
  author: string;
  createdAt: number;
}

export default class AddPosts implements IRunnableScript<IFirebaseDB> {
  async up(
    db: IFirebaseDB,
    info: IMigrationInfo,
    handler: FirebaseHandler
  ): Promise<string> {
    const postService = new EntityService<Post>(
      db.database,
      handler.cfg.buildPath('posts')
    );

    // Create posts with type safety
    await postService.create({
      title: 'First Post',
      author: 'user1',
      createdAt: Date.now()
    });

    return 'Created posts collection';
  }

  async down(
    db: IFirebaseDB,
    info: IMigrationInfo,
    handler: FirebaseHandler
  ): Promise<string> {
    await db.database.ref(handler.cfg.buildPath('posts')).remove();
    return 'Removed posts collection';
  }
}

3. Run Migrations

As a Library:

import { FirebaseRunner, FirebaseConfig } from '@migration-script-runner/firebase';

// Configure
const appConfig = new FirebaseConfig();
appConfig.folder = './migrations';
appConfig.tableName = 'schema_version';
appConfig.databaseUrl = process.env.FIREBASE_DATABASE_URL;
appConfig.applicationCredentials = process.env.GOOGLE_APPLICATION_CREDENTIALS;

// Initialize runner (handler creation is automatic)
const runner = await FirebaseRunner.getInstance({ config: appConfig });

// Run migrations
const result = await runner.migrate();
console.log(`Applied ${result.executed.length} migrations`);

// Rollback if needed
await runner.down();

With CLI:

# Run with inline credentials (easiest)
npx msr-firebase migrate \
  --database-url https://your-project.firebaseio.com \
  --credentials ./serviceAccountKey.json

# Or use environment variables
npx msr-firebase migrate

# Rollback last migration
npx msr-firebase down

# Check status
npx msr-firebase list --format table

Documentation

Getting Started

Using MSR Firebase

CLI Usage

Complete command-line interface documentation:

Library Usage

Programmatic API documentation:

API Reference

Complete API documentation:

Writing Migrations

Writing Migrations

Complete guide to writing migration scripts:


About

MSR Firebase is part of the Migration Script Runner ecosystem, providing database migration tooling for various database systems.


License

This project is licensed under the MIT License with Commons Clause and Attribution Requirements.

Based on Migration Script Runner Core by Volodymyr Lavrynovych.

Quick Summary

  • βœ… Free to use in your applications (including commercial)
  • βœ… Free to modify and contribute
  • ❌ Cannot sell this adapter or Firebase-specific extensions as standalone products
  • πŸ”’ Attribution required for Firebase migration extensions

See the LICENSE file and NOTICE file for detailed examples and FAQ.



Created with ❀️ by Volodymyr Lavrynovych in Ukraine πŸ‡ΊπŸ‡¦