Skip to main content

Overview

The Water Quality Backend API requires several environment variables for proper configuration. This guide documents all variables, their purpose, and how to configure them.

Getting Started

Copy the example environment file and customize it:
cp .env.example .env
Then edit .env with your actual credentials and configuration.
Never commit .env files to version control. The .env file contains sensitive credentials and should be kept secure.

Environment File Structure

The .env.example file provides a template:
# Core Authentication
FIREBASE_ADMIN_CREDENTIALS=''
FIREBASE_API_KEY=''
FIREBASE_REALTIME_URL=''
SECRET_KEY=''

# External Services
WEATHER_API_KEY=''
ONESIGNAL_APP_ID=''
ONESIGNAL_API_KEY=''
RESEND_API_KEY=''

# AI/ML Services
OPEN_ROUTER_KEY=""
OPEN_ROUTER_MODEL=""

# GitHub OAuth
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
GITHUB_CALLBACK_URL=
FRONTEND_ORIGIN=
APP_DEEP_LINK=aquaminds://login-success
STATE_SECRET=

# Firebase Admin SDK (Alternative)
FIREBASE_TYPE=service_account
FIREBASE_PROJECT_ID=
FIREBASE_PRIVATE_KEY_ID=
FIREBASE_PRIVATE_KEY=
FIREBASE_CLIENT_EMAIL=
FIREBASE_CLIENT_ID=
FIREBASE_AUTH_URI=https://accounts.google.com/o/oauth2/auth
FIREBASE_TOKEN_URI=https://oauth2.googleapis.com/token
FIREBASE_AUTH_PROVIDER_X509_CERT_URL=https://www.googleapis.com/oauth2/v1/certs
FIREBASE_CLIENT_X509_CERT_URL=
FIREBASE_UNIVERSE_DOMAIN=googleapis.com

Core Configuration

Authentication & Security

SECRET_KEY
string
required
Secret key used to sign JWT tokens with HS256 algorithm.How to generate:
python -c "import secrets; print(secrets.token_urlsafe(32))"
Example:
SECRET_KEY='xK8vN2pQ9mL4jR7wE5tY3uI6oP1aS0dF'
Keep this secret secure. If compromised, all JWT tokens can be forged.
STATE_SECRET
string
required
Secret used to HMAC-sign OAuth state parameters to prevent CSRF attacks.How to generate:
python -c "import secrets; print(secrets.token_urlsafe(32))"
Example:
STATE_SECRET='aB2cD4eF6gH8iJ0kL1mN3oP5qR7sT9uV'
Required for: GitHub OAuth flows

Firebase Configuration

The API uses Firebase for authentication and real-time database.
FIREBASE_ADMIN_CREDENTIALS
JSON string
required
Complete Firebase Admin SDK credentials as a JSON string.How to get:
  1. Go to Firebase Console → Project Settings → Service Accounts
  2. Click “Generate New Private Key”
  3. Download the JSON file
  4. Copy the entire JSON content as a string
Example:
FIREBASE_ADMIN_CREDENTIALS='{"type":"service_account","project_id":"your-project","private_key_id":"abc123","private_key":"-----BEGIN PRIVATE KEY-----\nMIIE...","client_email":"[email protected]"}'
Ensure the JSON is properly escaped if it contains special characters.
FIREBASE_API_KEY
string
required
Firebase Web API key for authentication requests.How to get: Firebase Console → Project Settings → General → Web API KeyExample:
FIREBASE_API_KEY='AIzaSyAbCdEfGhIjKlMnOpQrStUvWxYz123456'
Used for: Password authentication via Firebase Identity Toolkit
FIREBASE_REALTIME_URL
string
required
Firebase Realtime Database URL.Format: https://your-project-id.firebaseio.comExample:
FIREBASE_REALTIME_URL='https://water-quality-prod.firebaseio.com'
How to get: Firebase Console → Realtime Database → Data tab (URL is shown at top)

Alternative Method (Individual Fields)

Instead of FIREBASE_ADMIN_CREDENTIALS, you can provide individual fields:
FIREBASE_TYPE
string
Always service_account for server-side applications.Default: service_account
FIREBASE_PROJECT_ID
string
Your Firebase project ID.Example: water-quality-prod
FIREBASE_PRIVATE_KEY_ID
string
Private key ID from Firebase service account.
FIREBASE_PRIVATE_KEY
string
RSA private key (including -----BEGIN PRIVATE KEY----- headers).Note: Newlines should be preserved or escaped as \n
FIREBASE_CLIENT_EMAIL
string
Service account email address.Format: [email protected]
FIREBASE_CLIENT_ID
string
Service account client ID (numeric).
FIREBASE_AUTH_URI
string
OAuth2 authorization URI.Default: https://accounts.google.com/o/oauth2/auth
FIREBASE_TOKEN_URI
string
OAuth2 token URI.Default: https://oauth2.googleapis.com/token
FIREBASE_AUTH_PROVIDER_X509_CERT_URL
string
X.509 certificate URL for auth provider.Default: https://www.googleapis.com/oauth2/v1/certs
FIREBASE_CLIENT_X509_CERT_URL
string
X.509 certificate URL for service account.Format: https://www.googleapis.com/robot/v1/metadata/x509/[email protected]
FIREBASE_UNIVERSE_DOMAIN
string
Universe domain for Firebase.Default: googleapis.com

GitHub OAuth Configuration

GITHUB_CLIENT_ID
string
required
GitHub OAuth App client ID.How to get:
  1. Go to GitHub → Settings → Developer settings → OAuth Apps
  2. Create new OAuth App or use existing
  3. Copy the Client ID
Example:
GITHUB_CLIENT_ID='Iv1.a1b2c3d4e5f6g7h8'
GITHUB_CLIENT_SECRET
string
required
GitHub OAuth App client secret.How to get: Same location as Client ID → Generate new client secretExample:
GITHUB_CLIENT_SECRET='abc123def456ghi789jkl012mno345pqr678stu'
Keep this secret secure. Never expose in client-side code.
GITHUB_CALLBACK_URL
string
required
OAuth callback URL that GitHub redirects to after authorization.Format: https://your-api-domain.com/auth/github/callbackExample:
GITHUB_CALLBACK_URL='https://api.waterquality.com/auth/github/callback'
Important: This must match the callback URL configured in your GitHub OAuth App settings.
FRONTEND_ORIGIN
string
required
Frontend application URL where users are redirected after OAuth success (web).Format: https://your-frontend-domain.com/oauth/callbackExample:
FRONTEND_ORIGIN='https://app.waterquality.com/oauth/callback'
Used for: Web OAuth flow redirects
Mobile app deep link scheme for OAuth success redirects.Default: aquaminds://login-successExample:
APP_DEEP_LINK='waterquality://auth/callback'
Used for: Mobile OAuth flow redirects

External Services

Weather API

WEATHER_API_KEY
string
API key for weather data integration.Provider: Various (OpenWeatherMap, WeatherAPI, etc.)Example:
WEATHER_API_KEY='a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6'
Used for: Correlating water quality with weather conditions

Notifications

ONESIGNAL_APP_ID
string
OneSignal application ID for push notifications.How to get: OneSignal Dashboard → Settings → Keys & IDsExample:
ONESIGNAL_APP_ID='12345678-abcd-1234-efgh-1234567890ab'
ONESIGNAL_API_KEY
string
OneSignal REST API key.How to get: OneSignal Dashboard → Settings → Keys & IDs → REST API KeyExample:
ONESIGNAL_API_KEY='MzAwNjIwOTItZTNkYi00YjU2LTk2YmEtYjY4ODU2MjkyNjM0'
Used for: Sending alert notifications to mobile/web clients

Email Service

RESEND_API_KEY
string
Resend API key for transactional emails.How to get: Resend Dashboard → API KeysExample:
RESEND_API_KEY='re_123456789_abcdefghijklmnopqrstuvwxyz'
Used for: Password reset emails, alerts, notifications

AI/ML Configuration

OPEN_ROUTER_KEY
string
OpenRouter API key for AI model access.How to get: OpenRouter Dashboard → API KeysExample:
OPEN_ROUTER_KEY='sk-or-v1-1234567890abcdef1234567890abcdef1234567890abcdef1234567890ab'
Used for: AI-powered water quality analysis and predictions
OPEN_ROUTER_MODEL
string
OpenRouter model identifier to use.Example:
OPEN_ROUTER_MODEL='openai/gpt-4-turbo'
Popular models:
  • openai/gpt-4-turbo
  • anthropic/claude-3-opus
  • meta-llama/llama-3-70b-instruct

Optional Configuration

SKIP_FIREBASE_INIT
boolean
Skip Firebase initialization (useful for testing).Default: falseExample:
SKIP_FIREBASE_INIT='true'
Use case: Unit tests that don’t need Firebase connectivity

Configuration by Environment

Development

# .env.development
SECRET_KEY='dev-secret-key-change-in-production'
FIREBASE_API_KEY='your-dev-firebase-api-key'
FIREBASE_REALTIME_URL='https://water-quality-dev.firebaseio.com'
GITHUB_CALLBACK_URL='http://localhost:8000/auth/github/callback'
FRONTEND_ORIGIN='http://localhost:3000/oauth/callback'

# Optional: skip external services in dev
SKIP_FIREBASE_INIT='false'

Staging

# .env.staging
SECRET_KEY='staging-secret-key-different-from-prod'
FIREBASE_API_KEY='your-staging-firebase-api-key'
FIREBASE_REALTIME_URL='https://water-quality-staging.firebaseio.com'
GITHUB_CALLBACK_URL='https://api-staging.waterquality.com/auth/github/callback'
FRONTEND_ORIGIN='https://staging.waterquality.com/oauth/callback'

# Use staging services
ONESIGNAL_APP_ID='staging-onesignal-app-id'
RESEND_API_KEY='staging-resend-api-key'

Production

# .env.production
SECRET_KEY='production-secret-key-very-secure-32-chars-min'
STATE_SECRET='production-state-secret-different-from-jwt'
FIREBASE_ADMIN_CREDENTIALS='{...complete-json...}'
FIREBASE_API_KEY='production-firebase-api-key'
FIREBASE_REALTIME_URL='https://water-quality-prod.firebaseio.com'

# Production OAuth
GITHUB_CLIENT_ID='production-github-client-id'
GITHUB_CLIENT_SECRET='production-github-client-secret'
GITHUB_CALLBACK_URL='https://api.waterquality.com/auth/github/callback'
FRONTEND_ORIGIN='https://app.waterquality.com/oauth/callback'
APP_DEEP_LINK='waterquality://login-success'

# Production services
WEATHER_API_KEY='production-weather-api-key'
ONESIGNAL_APP_ID='production-onesignal-app-id'
ONESIGNAL_API_KEY='production-onesignal-api-key'
RESEND_API_KEY='production-resend-api-key'
OPEN_ROUTER_KEY='production-openrouter-key'
OPEN_ROUTER_MODEL='openai/gpt-4-turbo'

Docker Configuration

When deploying with Docker, pass environment variables via:

Docker Run

docker run -d \
  --name water-quality-api \
  --env-file .env \
  -p 8000:8000 \
  water-quality-api:latest

Docker Compose

services:
  app:
    build: .
    env_file:
      - .env
    # Or use environment directly:
    environment:
      - SECRET_KEY=${SECRET_KEY}
      - FIREBASE_API_KEY=${FIREBASE_API_KEY}
    ports:
      - "8000:8000"

Docker Secrets (Production)

For production, use Docker secrets:
services:
  app:
    build: .
    secrets:
      - firebase_credentials
      - jwt_secret
    environment:
      - FIREBASE_ADMIN_CREDENTIALS_FILE=/run/secrets/firebase_credentials
      - SECRET_KEY_FILE=/run/secrets/jwt_secret

secrets:
  firebase_credentials:
    external: true
  jwt_secret:
    external: true

Validation

Verify your configuration is correct:
# Test Firebase connection
curl -X POST http://localhost:8000/auth/login/ \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","password":"test"}'

# Test OAuth configuration
curl -L http://localhost:8000/auth/github/login/web

# Check application health
curl http://localhost:8000/

Security Best Practices

Critical Security Guidelines:
  1. Never commit .env files to version control
    echo ".env" >> .gitignore
    
  2. Use different secrets per environment
    • Development secrets should differ from production
    • Rotate secrets regularly (every 90 days recommended)
  3. Restrict access to .env files
    chmod 600 .env
    
  4. Use environment variable managers for production:
    • AWS Secrets Manager
    • HashiCorp Vault
    • Azure Key Vault
    • Google Cloud Secret Manager
  5. Validate required variables on startup: The application should fail fast if critical variables are missing
  6. Audit secret access: Log when secrets are accessed or modified

Troubleshooting

Error: Failed to initialize FirebasePossible causes:
  • Invalid FIREBASE_ADMIN_CREDENTIALS JSON
  • Incorrect FIREBASE_REALTIME_URL
  • Network connectivity issues
  • Firebase project permissions
Solution:
  1. Validate JSON syntax: python -c "import json; json.loads(open('.env').read().split('FIREBASE_ADMIN_CREDENTIALS=')[1].split('\n')[0])"
  2. Verify Firebase project exists and is active
  3. Check service account has proper permissions
Error: Token validation failedPossible causes:
  • SECRET_KEY mismatch between token creation and validation
  • SECRET_KEY changed after tokens were issued
Solution:
  • Ensure SECRET_KEY is consistent across all API instances
  • Re-authenticate to get new tokens
Error: invalid state signaturePossible causes:
  • STATE_SECRET not configured
  • STATE_SECRET changed during OAuth flow
  • State parameter tampered with
Solution:
  • Set STATE_SECRET in environment
  • Ensure STATE_SECRET is consistent across requests

Next Steps

Authentication

Learn how authentication uses these variables

Deployment

Deploy the API with proper configuration

Build docs developers (and LLMs) love