@valian/fireway
v1.0.2
Published
A schema migration tool for Firestore
Readme
Fireway
A schema migration tool for Firestore.
TypeScript, ESM JavaScript (.mjs), and CommonJS JavaScript (.cjs) are supported.
Usage
Create a migration file in the functions/migration (default directory).
Name the file in the format: v[semver]__[description].ts (TypeScript),
.mjs (ESM JavaScript), or .cjs (CommonJS JavaScript).
TypeScript example:
// ./migrations/v0.0.1__typescript_example.ts
import { type IMigrationFunctionsArguments } from '@valian/fireway'
export async function migrate({ firestore }: IMigrationFunctionsArguments) {
await firestore.collection('my_table').doc('document_id').set({ name: 'Fireway' })
}ESM JavaScript example:
// ./migrations/v0.0.1__javascript_example.mjs
export const migrate = async ({ firestore }) => {
await firestore.collection('my_table').doc('document_id').set({ name: 'Fireway' })
}CommonJS JavaScript example:
// ./migrations/v0.0.1__javascript_example.cjs
module.exports.migrate = async ({ firestore }) => {
await firestore.collection('my_table').doc('document_id').set({ name: 'Fireway' })
}Extended example
The library is using
Modular SDK for app
initialization. It is possible to use the app argument in migration scripts
to initialize another Firebase service, for example, auth.
// ./migrations/v0.2.0__typescript_extended_example.ts
import { type IMigrationFunctionsArguments } from '@valian/fireway'
import { getAuth } from 'firebase-admin/auth'
import { FieldValue } from 'firebase-admin/firestore'
export async function migrate({ firestore, app }: IMigrationFunctionsArguments) {
// Auth example
const firebaseAuth = getAuth(app)
const email = '[email protected]'
// search user identity
const user = await firebaseAuth.getUserByEmail(email)
if (!user) {
await firebaseAuth.createUser({
email: email,
emailVerified: true,
disabled: false,
})
}
// FieldValue example
await firestore.collection('table').doc('123').ref.update({
obsoleteField: FieldValue.delete(),
date: FieldValue.serverTimestamp(),
})
}Install
Install NPM package to Firebase functions projects:
npm i @valian/fireway
Fireway uses jiti to automatically handle
TypeScript, ESM, and CommonJS migration files, so no additional configuration
is required for TypeScript support.
Running locally
Most likely you'll want to test your migration scripts locally first before running them against Cloud instances.
Ensure that Firestore emulator is set up in
firebase.jsonfile.{ "emulators": { "firestore": { "port": 8080 } } }Start your local emulators with
firebase emulators:startRun migrations.
To connect to the local emulator
GCLOUD_PROJECTenvironment variable is required pointing to your projectId. Check.firebasercfile and the{ "projects": { "default": "[project-id]" }}settings. If it is not specified, any value can be provided, e.g. "local".
SpecifyFIRESTORE_EMULATOR_HOSTvariable pointing to your local emulator (default Firestore port is8080).GCLOUD_PROJECT=project-id FIRESTORE_EMULATOR_HOST=localhost:8080 fireway migrateFireway automatically handles TypeScript, ESM (
.mjs), and CommonJS (.cjs) files without any additional configuration.
Migration results
Migration results are stored in the fireway collection (can be changed) in
Firestore in the format v[semver]__[description].
// fireway/v0.0.1__typescript_example
{
installed_rank: 3, // 0-based sequence
checksum: 'fdfe6a55a7c97a4346cb59871b4ce97c',
description: 'typescript_example',
execution_time: 1221,
installed_by: 'system_user_name',
installed_on: Timestamp(),
script: 'v0.0.1__typescript_example.ts',
type: 'ts', // or 'mjs' for ESM, 'cjs' for CommonJS
version: '0.0.1',
success: true
}Re-running script
If script execution failed, the workflow will be stopped. Running migration again will start from the latest failed script.
Generate a Firebase Service Account JSON key by opening: Project Settings -> Service Accounts -> Generate new private key. Private key will have the admin role and contain your project settings.
Set up CI provider to use that key. For Github Actions, add a secret to the Github repository, e.g.
FIREBASE_SERVICE_ACCOUNT_JSON_DEV.In the Github workflow use
google-github-actions/auth@v1to load the credentialsjobs: build_and_deploy: runs-on: ubuntu-latest name: Dev workflow steps: - uses: actions/checkout@v3 - name: 'NPP install and build steps' run: | echo "your scripts" - name: 'Authenticate to Google Cloud' uses: 'google-github-actions/auth@v1' with: credentials_json: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_JSON_DEV }}' create_credentials_file: true cleanup_credentials: true - name: Deploy functions and run migrations run: | npm run migrate firebase deploy --only functionswhere
package.jsonscripts section has:"migrate": "fireway migrate"
Alternatively use GOOGLE_APPLICATION_CREDENTIALS environment variable as
described in
Firebase Admin Auth instructions.
CLI
Usage
$ fireway migrate [options]
Available Commands
migrate Migrates schema to the latest version
For more info, run any command with the `--help` flag
$ fireway migrate --help
Options
--path Path to migration files (default "./migrations")
--collection Firebase collection name for migration results (default "fireway")
--dryRun Simulates changes
--logLevel Log level, options: debug, log, warn, error (default "log")
-v, --version Displays current version
-h, --help Displays this messageContributing
Fork the repository, make changes, ensure that project is tested:
pnpm install
npm run build && pnpm run testHistory
Based on ace-devs/fireway work, which was inspired by kevlened/fireway
License
MIT
