Skip to main content

@firebase-backup-platform/backup-core

The backup-core package provides the core orchestration layer for FireBackup. It coordinates the entire backup and restore process, integrating with Firebase, compression, encryption, and storage connectors.

Installation

npm install @firebase-backup-platform/backup-core
# or
yarn add @firebase-backup-platform/backup-core

Overview

The backup-core package is the heart of FireBackup's backup engine. It handles:

  • Firebase Firestore data export
  • Firebase Authentication user export
  • Compression and encryption orchestration
  • Storage upload coordination
  • Progress tracking and event emission
  • Restore operations with document mapping

Quick Start

Basic Backup

import { BackupCore } from '@firebase-backup-platform/backup-core';
import { createStorageConnector } from '@firebase-backup-platform/storage-connectors';

// Configure the backup core
const backupCore = new BackupCore({
firebase: {
projectId: 'my-firebase-project',
credentials: require('./service-account.json')
},
storage: createStorageConnector({
type: 's3',
bucket: 'my-backups',
region: 'us-east-1',
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
}
}),
encryption: {
enabled: true,
key: process.env.ENCRYPTION_KEY
},
compression: {
enabled: true,
algorithm: 'brotli'
}
});

// Run backup
const result = await backupCore.backup({
collections: ['users', 'orders', 'products'],
includeAuth: true,
backupPath: 'backups/2024-01-15'
});

console.log('Backup completed:', result);

Quick Backup Helper

For simple use cases, use the quickBackup helper:

import { quickBackup } from '@firebase-backup-platform/backup-core';

const result = await quickBackup({
firebase: {
projectId: 'my-project',
credentials: serviceAccount
},
storage: {
type: 's3',
bucket: 'my-backups',
region: 'us-east-1'
}
}, {
collections: ['users'],
backupPath: 'backups/quick'
});

API Reference

BackupCore Class

The main class for orchestrating backup operations.

Constructor

new BackupCore(config: BackupCoreConfig)

BackupCoreConfig:

PropertyTypeRequiredDescription
firebaseFirebaseConfigYesFirebase connection configuration
storageStorageConnectorYesStorage connector instance
encryptionEncryptionConfigNoEncryption settings
compressionCompressionConfigNoCompression settings
loggerLoggerNoCustom logger instance

Methods

backup(options)

Creates a backup of specified collections.

async backup(options: BackupOptions): Promise<BackupResult>

BackupOptions:

PropertyTypeDefaultDescription
collectionsstring[]AllCollections to backup
excludeCollectionsstring[][]Collections to exclude
includeAuthbooleanfalseInclude Firebase Auth users
includeSubcollectionsbooleantrueInclude subcollections
backupPathstringAuto-generatedStorage path for backup
metadataobject{}Custom metadata to include
onProgressfunction-Progress callback

BackupResult:

interface BackupResult {
id: string;
path: string;
size: number;
sizeFormatted: string;
collections: string[];
documentCount: number;
authUserCount?: number;
duration: number;
durationFormatted: string;
checksum: string;
createdAt: Date;
metadata: object;
}

Example:

const result = await backupCore.backup({
collections: ['users', 'orders'],
includeAuth: true,
backupPath: 'backups/2024-01-15/full',
onProgress: (progress) => {
console.log(`Progress: ${progress.percent}%`);
console.log(`Processing: ${progress.currentCollection}`);
console.log(`Documents: ${progress.documentsProcessed}`);
}
});
restore(options)

Restores data from a backup.

async restore(options: RestoreOptions): Promise<RestoreResult>

RestoreOptions:

PropertyTypeDefaultDescription
backupPathstringRequiredPath to backup file
collectionsstring[]AllCollections to restore
restoreAuthbooleanfalseRestore Auth users
modeRestoreMode'merge'How to handle existing docs
dryRunbooleanfalsePreview without writing
onProgressfunction-Progress callback

RestoreMode:

ModeDescription
'merge'Merge with existing documents
'overwrite'Replace existing documents
'skip'Skip existing documents

Example:

const result = await backupCore.restore({
backupPath: 'backups/2024-01-15/full',
collections: ['users'],
mode: 'merge',
dryRun: true, // Preview first
onProgress: (progress) => {
console.log(`Restored: ${progress.documentsRestored}`);
}
});

// If dry run looks good, run actual restore
if (result.preview) {
console.log('Preview:', result.preview);
// Run without dryRun to actually restore
}
verify(options)

Verifies backup integrity.

async verify(options: VerifyOptions): Promise<VerifyResult>

Example:

const verification = await backupCore.verify({
backupPath: 'backups/2024-01-15/full'
});

console.log('Valid:', verification.valid);
console.log('Checksum match:', verification.checksumMatch);
console.log('Document count:', verification.documentCount);
list(options)

Lists available backups.

async list(options?: ListOptions): Promise<BackupInfo[]>

Example:

const backups = await backupCore.list({
prefix: 'backups/2024-01',
limit: 10
});

for (const backup of backups) {
console.log(`${backup.path} - ${backup.sizeFormatted} - ${backup.createdAt}`);
}
delete(path)

Deletes a backup.

async delete(path: string): Promise<void>

Example:

await backupCore.delete('backups/2024-01-15/full');
console.log('Backup deleted');

Configuration

FirebaseConfig

interface FirebaseConfig {
projectId: string;
credentials: ServiceAccount | string; // Object or path to file
databaseURL?: string;
}

Using service account object:

const config = {
firebase: {
projectId: 'my-project',
credentials: {
type: 'service_account',
project_id: 'my-project',
private_key_id: '...',
private_key: '-----BEGIN PRIVATE KEY-----\n...',
client_email: 'firebase-adminsdk@my-project.iam.gserviceaccount.com',
// ... rest of service account
}
}
};

Using file path:

const config = {
firebase: {
projectId: 'my-project',
credentials: './path/to/service-account.json'
}
};

Using environment variable:

const config = {
firebase: {
projectId: process.env.FIREBASE_PROJECT_ID,
credentials: JSON.parse(process.env.FIREBASE_CREDENTIALS)
}
};

EncryptionConfig

interface EncryptionConfig {
enabled: boolean;
algorithm?: 'aes-256-gcm'; // Currently only supported algorithm
key: string | Buffer; // 32-byte key for AES-256
keyDerivation?: {
enabled: boolean;
salt?: string;
iterations?: number;
};
}

Example:

const config = {
encryption: {
enabled: true,
key: process.env.ENCRYPTION_KEY, // Base64-encoded 32-byte key
keyDerivation: {
enabled: true,
salt: process.env.KEY_SALT,
iterations: 100000
}
}
};

CompressionConfig

interface CompressionConfig {
enabled: boolean;
algorithm?: 'brotli' | 'gzip' | 'none';
level?: number; // 1-9 for gzip, 1-11 for brotli
}

Example:

const config = {
compression: {
enabled: true,
algorithm: 'brotli',
level: 6 // Good balance of speed/ratio
}
};

Events

BackupCore emits events for monitoring progress:

import { BackupCore } from '@firebase-backup-platform/backup-core';

const backupCore = new BackupCore(config);

// Backup events
backupCore.on('backup:start', (data) => {
console.log('Backup started:', data.backupId);
});

backupCore.on('backup:progress', (data) => {
console.log(`Progress: ${data.percent}%`);
console.log(`Collection: ${data.currentCollection}`);
console.log(`Documents: ${data.documentsProcessed}/${data.totalDocuments}`);
});

backupCore.on('backup:collection:complete', (data) => {
console.log(`Completed collection: ${data.collection}`);
console.log(`Documents: ${data.documentCount}`);
});

backupCore.on('backup:complete', (data) => {
console.log('Backup complete:', data.result);
});

backupCore.on('backup:error', (error) => {
console.error('Backup failed:', error);
});

// Restore events
backupCore.on('restore:start', (data) => {
console.log('Restore started');
});

backupCore.on('restore:progress', (data) => {
console.log(`Restored: ${data.documentsRestored}`);
});

backupCore.on('restore:complete', (data) => {
console.log('Restore complete:', data.result);
});

Advanced Usage

Incremental Backups

// First, create a full backup
const fullBackup = await backupCore.backup({
collections: ['users', 'orders'],
backupPath: 'backups/full/2024-01-15'
});

// Later, create an incremental backup
const incrementalBackup = await backupCore.backup({
collections: ['users', 'orders'],
backupPath: 'backups/incremental/2024-01-16',
incremental: {
enabled: true,
basePath: 'backups/full/2024-01-15',
since: new Date('2024-01-15T00:00:00Z')
}
});

Parallel Collection Processing

const result = await backupCore.backup({
collections: ['users', 'orders', 'products', 'reviews'],
parallel: {
enabled: true,
maxConcurrency: 4
}
});

Custom Document Filtering

const result = await backupCore.backup({
collections: ['users'],
filter: {
users: {
// Only backup active users
where: [
{ field: 'status', operator: '==', value: 'active' }
]
}
}
});

Stream-Based Processing

For very large collections, use streaming:

const stream = backupCore.createBackupStream({
collections: ['large_collection'],
chunkSize: 10000 // Process 10k documents at a time
});

stream.on('data', (chunk) => {
console.log(`Processed chunk: ${chunk.documentCount} documents`);
});

stream.on('end', () => {
console.log('Stream complete');
});

Custom Transformers

Transform documents during backup:

const result = await backupCore.backup({
collections: ['users'],
transformers: {
users: (doc) => {
// Remove sensitive fields
const { password, ssn, ...safeDoc } = doc;
return safeDoc;
}
}
});

Error Handling

import {
BackupCore,
BackupError,
FirebaseConnectionError,
StorageError,
EncryptionError,
ValidationError
} from '@firebase-backup-platform/backup-core';

try {
await backupCore.backup(options);
} catch (error) {
if (error instanceof FirebaseConnectionError) {
console.error('Firebase connection failed:', error.message);
// Handle reconnection
} else if (error instanceof StorageError) {
console.error('Storage operation failed:', error.message);
// Handle storage issues
} else if (error instanceof EncryptionError) {
console.error('Encryption failed:', error.message);
// Handle encryption issues
} else if (error instanceof ValidationError) {
console.error('Validation failed:', error.message);
// Handle validation errors
} else if (error instanceof BackupError) {
console.error('Backup error:', error.message);
console.error('Code:', error.code);
console.error('Details:', error.details);
}
}

Best Practices

Performance Optimization

// Use batch processing for large collections
const result = await backupCore.backup({
collections: ['large_collection'],
batchSize: 5000, // Process 5000 docs per batch
parallel: {
enabled: true,
maxConcurrency: 2
}
});

Memory Management

// For very large backups, use streaming mode
const result = await backupCore.backup({
collections: ['huge_collection'],
streaming: {
enabled: true,
chunkSize: 10000,
flushInterval: 5000 // Flush every 5 seconds
}
});

Retry Configuration

const backupCore = new BackupCore({
...config,
retry: {
maxAttempts: 3,
initialDelay: 1000,
maxDelay: 30000,
backoffMultiplier: 2
}
});

TypeScript Support

Full TypeScript support with comprehensive type definitions:

import {
BackupCore,
BackupCoreConfig,
BackupOptions,
BackupResult,
RestoreOptions,
RestoreResult,
VerifyResult,
BackupInfo,
ProgressCallback,
BackupError
} from '@firebase-backup-platform/backup-core';

// Fully typed configuration
const config: BackupCoreConfig = {
firebase: {
projectId: 'my-project',
credentials: serviceAccount
},
storage: connector,
encryption: {
enabled: true,
key: encryptionKey
}
};

// Typed options and results
const options: BackupOptions = {
collections: ['users'],
includeAuth: true
};

const result: BackupResult = await backupCore.backup(options);