A schema migration tool for Firestore
npm install @valian/firewayA schema migration tool for Firestore.
TypeScript, ESM JavaScript (.mjs), and CommonJS JavaScript (.cjs) are supported.
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:
``ts
// ./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:
`js
// ./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:
`js
// ./migrations/v0.0.1__javascript_example.cjs
module.exports.migrate = async ({ firestore }) => {
await firestore.collection('my_table').doc('document_id').set({ name: 'Fireway' })
}
`
The library is using
Modular SDK for app
initialization. It is possible to use the app argument in migration scriptsauth
to initialize another Firebase service, for example, .
`ts
// ./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 = 'test-user@test.com'
// 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(),
})
}
`
1. Install NPM package to Firebase functions projects:
`bash`
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.
Most likely you'll want to test your migration scripts _locally_ first before
running them against Cloud instances.
1. Ensure that
Firestore emulator
is set up in firebase.json file.
`json`
{
"emulators": {
"firestore": {
"port": 8080
}
}
}
2. Start your local emulators with
`bash`
firebase emulators:start
3. Run migrations.
To connect to the local emulator GCLOUD_PROJECT environment variable is.firebaserc
required pointing to your projectId. Check file and the{ "projects": { "default": "[project-id]" }}
settings. If it is notFIRESTORE_EMULATOR_HOST
specified, any value can be provided, e.g. "local".
Specify variable pointing to your local emulator8080
(default Firestore port is ).
`bash`
GCLOUD_PROJECT=project-id FIRESTORE_EMULATOR_HOST=localhost:8080 fireway migrate
Fireway automatically handles TypeScript, ESM (.mjs), and CommonJS.cjs
() files without any additional configuration.
Migration results are stored in the fireway collection (can be changed) inFirestore in the format v[semver]__[description].
`js
// 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
}
`
If script execution failed, the workflow will be stopped. Running migration
again will start from the latest failed script.
1. 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.
2. 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@v1 to load the
credentials
`yaml`
jobs:
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 functions
where package.json scripts section has:
`json`
"migrate": "fireway migrate"
Alternatively use GOOGLE_APPLICATION_CREDENTIALS environment variable as
described in
Firebase Admin Auth instructions.
`bash
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 message
`
Fork the repository, make changes, ensure that project is tested:
`bash``
pnpm install
npm run build && pnpm run test
Based on ace-devs/fireway work, which
was inspired by kevlened/fireway
MIT