Firebase Setup

Complete guide to configuring Firebase backend services

Firebase Services Overview

MissΓ£o uses the following Firebase services:

Authentication

Email/Password, Google Sign-In, and Apple Sign-In for user authentication.

Cloud Firestore

NoSQL database for storing users, parishes, events, and admin data.

Cloud Storage

File storage for images (parish photos, user avatars, event images).

Cloud Functions

Server-side logic for admin operations, notifications, and data processing.

Cloud Messaging (FCM)

Push notifications for iOS, Android, and Web platforms.

Firebase Hosting

Web hosting for the Admin Panel and Widgetbook documentation.

πŸ’° Firebase Billing Information

Blaze Plan Required

Cloud Functions require the Firebase Blaze (pay-as-you-go) plan. You cannot deploy functions on the free Spark plan.

Cost Varies by Usage

Firebase charges based on usage (reads, writes, function invocations, storage, bandwidth). Small apps typically stay within free tier limits.

You Are Responsible for Billing

All Firebase costs are your responsibility. We strongly recommend setting up budget alerts in Google Cloud Console.

Step 1: Create a Firebase Project

  1. Go to Firebase Console
  2. Click "Add project" or "Create a project"
  3. Enter your project name (e.g., "my-church-app")
  4. Accept the terms and continue
  5. Enable or disable Google Analytics (recommended: enable)
  6. If enabling Analytics, select or create a Google Analytics account
  7. Click "Create project"
Project ID: Note your project ID (shown as "project-name-xxxxx"). You'll need this for configuration.

Step 2: Enable Authentication

  1. In Firebase Console, go to Build β†’ Authentication
  2. Click "Get started"
  3. Enable the following sign-in providers:

Email/Password

  1. Click on "Email/Password"
  2. Toggle "Enable" to ON
  3. Optionally enable "Email link (passwordless sign-in)"
  4. Click "Save"

Google Sign-In

  1. Click on "Google"
  2. Toggle "Enable" to ON
  3. Add a support email address
  4. Click "Save"

Apple Sign-In (for iOS)

  1. Click on "Apple"
  2. Toggle "Enable" to ON
  3. Configure your Apple Developer credentials:
    • Services ID
    • Apple Team ID
    • Key ID and Private Key
  4. Click "Save"
Apple Developer Account: Apple Sign-In requires an Apple Developer account ($99/year). See Apple's documentation.

Step 3: Set Up Firestore Database

  1. Go to Build β†’ Firestore Database
  2. Click "Create database"
  3. Choose "Start in production mode"
  4. Select your database location:
    • Brazil: southamerica-east1 (SΓ£o Paulo)
    • US: us-central1
    • Europe: europe-west1
  5. Click "Enable"
Location is permanent! Choose carefully - you cannot change the database location after creation.

Deploy Security Rules

The project includes pre-configured security rules. Deploy them with:

firebase deploy --only firestore:rules

Deploy Firestore Indexes (Required)

Important: Firestore indexes are required for the app to function properly. Without indexes, queries will fail with "index required" errors, and features like the admin dashboard, parish search, and event listings won't work.

The project includes pre-configured composite indexes in firestore.indexes.json. Deploy them with:

firebase deploy --only firestore:indexes

Note: Index creation can take several minutes. You can monitor the progress in:

  1. Go to Firebase Console
  2. Select your project
  3. Go to Firestore Database β†’ Indexes
  4. Wait until all indexes show status "Enabled" (green checkmark)

Indexes Included

Collection Purpose
parishes Geolocation search, popularity sorting, filtering by status/city/state
events Event listings by parish, date filtering, status filtering
sessions Active session queries for analytics
admin_notifications Admin notification listing with pagination
Troubleshooting: If you see "The query requires an index" errors in the console, the indexes haven't finished building yet. Wait a few minutes and try again, or check the Indexes tab in Firebase Console.

Firestore Collections Structure

Collection Description
users User profiles and preferences
parishes Parish information and details
events Parish events and schedules
admins Admin panel users and roles
notifications Push notification records
mail Email queue (for Trigger Email extension)

Step 4: Set Up Cloud Storage

  1. Go to Build β†’ Storage
  2. Click "Get started"
  3. Choose "Start in production mode"
  4. Select the same location as your Firestore database
  5. Click "Done"

Deploy Storage Rules

firebase deploy --only storage

Storage Structure

gs://your-project.appspot.com/
β”œβ”€β”€ parishes/
β”‚   └── {parishId}/
β”‚       β”œβ”€β”€ photos/       # Parish photos
β”‚       └── logo/         # Parish logo
β”œβ”€β”€ users/
β”‚   └── {userId}/
β”‚       └── avatar/       # User profile picture
└── events/
    └── {eventId}/
        └── images/       # Event images

Step 5: Deploy Cloud Functions

Upgrade to Blaze Plan

Cloud Functions require the Blaze (pay-as-you-go) plan:

  1. Click the βš™οΈ gear icon in the Firebase Console
  2. Select "Usage and billing"
  3. Click "Modify plan"
  4. Select "Blaze" and add a billing account
Billing tip: Set up budget alerts in the Google Cloud Console to avoid unexpected charges.

Deploy Functions

# Navigate to project root
cd ~/projects/missao

# Deploy all functions
firebase deploy --only functions

Available Cloud Functions

Function Type Description
validateAdminAccess Callable Validates admin authentication and role
inviteAdmin Callable Creates new admin invitation
updateAdminRole Callable Updates admin permissions
revokeAdminAccess Callable Deactivates admin account
getAdminsPaginated Callable Lists admins with pagination
getDashboardMetrics Callable Dashboard statistics
sendPushNotification Callable Sends push notifications

Configure Public Access for Cloud Functions (Required)

Important: Firebase Cloud Functions Gen 2 run on Google Cloud Run and require public invocation permissions to be called from web/mobile apps. Without this configuration, you'll receive "unauthenticated" errors.

After deploying, you must allow public invocation for each callable function. There are two ways to do this:

Option 1: Using Google Cloud Console (Recommended)

  1. Go to Google Cloud Console β†’ Cloud Run
  2. Select your Firebase project from the project dropdown at the top
  3. You'll see a list of services - each Cloud Function is a service
  4. For each callable function (e.g., validateAdminAccess):
    1. Click on the function name
    2. Go to the "Security" tab
    3. Under "Authentication", select "Allow unauthenticated invocations"
    4. Click "Save"
  5. Repeat for all callable functions

Option 2: Using gcloud CLI

Install the Google Cloud SDK and run:

# Authenticate with Google Cloud
gcloud auth login

# Set your project
gcloud config set project YOUR_PROJECT_ID

# Grant public access to each function
# Replace FUNCTION_NAME and REGION with your values

gcloud functions add-invoker-policy-binding validateAdminAccess \
  --region=southamerica-east1 \
  --member="allUsers"

gcloud functions add-invoker-policy-binding inviteAdmin \
  --region=southamerica-east1 \
  --member="allUsers"

gcloud functions add-invoker-policy-binding updateAdminRole \
  --region=southamerica-east1 \
  --member="allUsers"

gcloud functions add-invoker-policy-binding revokeAdminAccess \
  --region=southamerica-east1 \
  --member="allUsers"

gcloud functions add-invoker-policy-binding getAdminsPaginated \
  --region=southamerica-east1 \
  --member="allUsers"

gcloud functions add-invoker-policy-binding getDashboardMetrics \
  --region=southamerica-east1 \
  --member="allUsers"

gcloud functions add-invoker-policy-binding sendPushNotification \
  --region=southamerica-east1 \
  --member="allUsers"

gcloud functions add-invoker-policy-binding updateAdminLastLogin \
  --region=southamerica-east1 \
  --member="allUsers"
Region: If you deployed functions to a different region, replace southamerica-east1 with your region (e.g., us-central1, europe-west1).
Security Note: "Allow unauthenticated invocations" means the Cloud Run service can be called without a Google Cloud IAM token. However, your functions still validate Firebase Authentication tokens internally - only authenticated Firebase users can execute admin operations. This is the standard pattern for Firebase callable functions.

Step 6: Configure Cloud Messaging (FCM)

iOS Configuration

  1. Generate an APNs key in Apple Developer Console
  2. Go to Firebase Console β†’ Project Settings β†’ Cloud Messaging
  3. Under "Apple app configuration", upload your APNs key

Android Configuration

Android is configured automatically when you add google-services.json to your project.

Web Configuration

Generate a VAPID key for web push notifications:

  1. Go to Project Settings β†’ Cloud Messaging
  2. Under "Web configuration", click "Generate key pair"
  3. Copy the key and add it to your environment configuration

Step 7: Set Up Firebase Hosting

Configure hosting targets for the Admin Panel:

# Add hosting target for admin panel
firebase target:apply hosting admin YOUR_PROJECT_ID

# Deploy (after building)
flutter build web --dart-define-from-file=.env.prod
firebase deploy --only hosting:admin

The firebase.json already includes the hosting configuration with:

Step 8: Install Extensions (Optional)

Trigger Email Extension

For sending emails (admin invitations, password resets):

  1. Go to Extensions in Firebase Console
  2. Search for "Trigger Email"
  3. Click "Install"
  4. Configure with your SMTP provider (SendGrid recommended):
    SMTP_CONNECTION_URI=smtps://apikey:YOUR_API_KEY@smtp.sendgrid.net:465
    MAIL_COLLECTION=mail
    DEFAULT_FROM=noreply@yourdomain.com
SendGrid: Create a free account at sendgrid.com and generate an API key.

Step 9: Configure FlutterFire

Run FlutterFire CLI to generate platform configurations:

# Ensure FlutterFire CLI is installed
dart pub global activate flutterfire_cli

# Configure Firebase
flutterfire configure --project=YOUR_PROJECT_ID

This generates:

Important: Run this command every time you add a new platform or change Firebase project settings.

Step 10: Create First Admin User

After deploying Cloud Functions, create your first admin:

Option 1: Using Firebase Console

  1. Go to Authentication β†’ Users
  2. Add a new user with email/password
  3. Go to Firestore β†’ admins collection
  4. Create a document with the user's UID:
{
  "uid": "USER_UID_HERE",
  "email": "admin@example.com",
  "displayName": "Super Admin",
  "role": "super_admin",
  "status": "active",
  "createdAt": Timestamp,
  "createdBy": "system"
}

Option 2: Using Firebase CLI

# This requires a custom script (included in functions/scripts/)
node functions/scripts/create-admin.js --email=admin@example.com --role=super_admin

Step 11: Firebase App Check (Optional)

App Check adds an extra layer of security by verifying that requests come from your legitimate apps, protecting your backend from abuse and unauthorized access.

Is App Check required? No, it's optional. Your Firebase Security Rules already protect your data. App Check is recommended for production apps with high traffic or when you want additional protection against bots and unauthorized API access.

When to Use App Check

Enable App Check in Firebase Console

  1. Go to Build β†’ App Check in Firebase Console
  2. Click "Get started"
  3. Register your apps with their respective attestation providers

iOS Configuration

  1. In Firebase Console β†’ App Check, click on your iOS app
  2. Select DeviceCheck or App Attest:
    • DeviceCheck: Works on iOS 11+, simpler setup
    • App Attest: More secure, iOS 14+ only
  3. Click "Save"

Android Configuration

  1. In Firebase Console β†’ App Check, click on your Android app
  2. Select Play Integrity
  3. Enable Play Integrity API in Google Cloud Console
  4. Click "Save"

Web Configuration

  1. In Firebase Console β†’ App Check, click on your Web app
  2. Select reCAPTCHA v3
  3. Create a reCAPTCHA v3 site key at reCAPTCHA Admin
  4. Enter the site key and click "Save"

Flutter Code Setup

Add firebase_app_check to your project:

# Add dependency
flutter pub add firebase_app_check

Initialize App Check in your main.dart:

import 'package:firebase_app_check/firebase_app_check.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );

  // Initialize App Check
  await FirebaseAppCheck.instance.activate(
    // iOS provider
    appleProvider: AppleProvider.deviceCheck, // or .appAttest
    // Android provider
    androidProvider: AndroidProvider.playIntegrity,
    // Web provider (requires reCAPTCHA site key)
    webProvider: ReCaptchaV3Provider('YOUR_RECAPTCHA_SITE_KEY'),
  );

  runApp(MyApp());
}

Enforce App Check (After Testing)

Once you've verified App Check works correctly:

  1. Go to Firebase Console β†’ App Check
  2. Click on each Firebase service (Firestore, Storage, Functions)
  3. Click "Enforce"
Warning: Only enforce App Check after thorough testing! Enforcing before your apps are properly configured will block all requests from your apps.

Debug Provider (Development)

For local development and testing, use the debug provider:

await FirebaseAppCheck.instance.activate(
  appleProvider: AppleProvider.debug,
  androidProvider: AndroidProvider.debug,
);
Debug Token: When using debug provider, App Check will print a debug token to the console. Add this token to Firebase Console β†’ App Check β†’ Apps β†’ Manage debug tokens.

Firebase Emulators (Development)

For local development, use Firebase Emulators:

# Start all emulators
firebase emulators:start

# Start specific emulators
firebase emulators:start --only auth,firestore,functions

Emulator ports (configured in firebase.json):

Service Port URL
Auth 9099 http://localhost:9099
Firestore 8080 http://localhost:8080
Functions 5001 http://localhost:5001
Storage 9199 http://localhost:9199
Hosting 5000 http://localhost:5000
Emulator UI 4002 http://localhost:4002
Tip: The Emulator UI at port 4002 provides a visual interface for managing Auth users, Firestore data, and viewing function logs.

Next Steps

With Firebase configured, proceed to:

  1. Configuration - Set up environment variables and API keys
  2. Deployment - Deploy to production