Skip to content

Staging Environment Setup

Master Schedule uses two completely separate Firebase projects — one for production and one for staging — so that test data never touches real school data. Each project has its own Firestore database, Authentication user pool, and four Hosting sites.

Production Staging
Firebase project masterschedule-prod masterschedule-staging
Public site masterschedule.app masterschedule-public-staging.web.app
App URL app.masterschedule.app masterschedule-app-staging.web.app
Help URL help.masterschedule.app masterschedule-help-staging.web.app
Admin URL admin.masterschedule.app masterschedule-admin-staging.web.app

Project structure

masterschedule-prod              (Firebase project)
├── masterschedule-public        Public marketing site
├── masterschedule-app           Main scheduling app
├── masterschedule-help          Help documentation
└── masterschedule-admin         Admin console

masterschedule-staging           (Firebase project)
├── masterschedule-public-staging
├── masterschedule-app-staging
├── masterschedule-help-staging
└── masterschedule-admin-staging

One-time setup

1. Enable Firestore and Authentication in each project

In both masterschedule-prod and masterschedule-staging:

  1. Go to Build → Firestore Database → Create database (production mode).
  2. Go to Authentication → Sign-in method and enable the Google provider.

2. Deploy security rules

./deploy.sh --rules-staging
./deploy.sh --rules-prod     # prompts for confirmation

3. Set up the Firestore TTL policy

Follow the same steps in each project — see Audit Log TTL Policy Setup.

4. Add yourself as superadmin

In each project's Firestore, create a document at superadmins/{your-uid}:

email:     "your@email.com"
grantedAt: <current timestamp>

Find your UID in Authentication → Users for each project.


Deploying to staging

# App + admin + public site
./deploy.sh --staging

# Help docs only
./deploy.sh --help-staging

# Rules only
./deploy.sh --rules-staging

# Everything at once
./deploy.sh --all

The deploy script automatically injects the correct Firebase config (including the per-site appId) before uploading, then restores the production config when finished so local development is unaffected.


Deploying to production

# App + admin + public site (prompts for confirmation)
./deploy.sh --production

# Help docs (prompts for confirmation)
./deploy.sh --help-prod

# Rules (prompts for confirmation)
./deploy.sh --rules-prod

Firebase config management

Each site has its own Firebase web app registration and appId. All shared credentials (API key, project ID, etc.) are stored in env/firebase.prod.json and env/firebase.staging.json. The deploy script picks the correct appId per site automatically.

To write config files manually without deploying:

./deploy.sh --write-config staging
./deploy.sh --write-config prod

Loading test data

Production data must never be copied directly to staging. Use one of:

  • Manually created test data — create schools, teachers, and courses by hand in the staging app. This is the required approach until the data sanitizer is built.
  • Data sanitizer (pending) — a script that anonymizes a production Firestore export and imports it into staging. See Data Architecture.

Security rules

Both projects run the same firestore.rules and storage.rules files. When you change rules, deploy to both:

./deploy.sh --rules

This deploys to staging first, then prompts before deploying to production.