Files
crowd-funder-for-time-pwa/doc/android-firebase-gms.md

3.9 KiB

Android — Firebase, Google Play Services, and FOSS Distribution

Overview

The app is designed to work on Android devices with and without Google Play Services (GMS). Firebase/FCM push notifications are an opt-in feature at build time; all other functionality works on GMS-less devices (F-Droid, LineageOS without OpenGApps, etc.).

How the opt-in guard works

android/app/build.gradle applies the com.google.gms.google-services Gradle plugin only when both conditions are true:

  1. android/google-services.json is present on disk
  2. The Gradle property firebaseEnabled is explicitly passed
if (servicesJSON.exists() && servicesJSON.text && project.hasProperty('firebaseEnabled')) {
    apply plugin: 'com.google.gms.google-services'
}

This means the file can live on disk for development purposes without accidentally activating Firebase.

Build commands

Target Command Firebase
APK / sideload / Zapstore ./gradlew assembleRelease off
Aurora / Play Store without FCM ./gradlew bundleRelease off
Play Store with FCM push notifications ./gradlew bundleRelease -PfirebaseEnabled on
F-Droid ./gradlew assembleRelease off (required)

Behavior on non-GMS devices

When built with -PfirebaseEnabled, Firebase SDKs check for GMS availability at startup and degrade gracefully if it is absent:

  • Firebase initializes but detects no GMS
  • FCM skips token registration silently (no token, no notifications)
  • The app continues to work normally

This means a single Play Store AAB (bundleRelease -PfirebaseEnabled) covers both GMS and non-GMS users. GMS users get push notifications; non-GMS users get a fully functional app without them.

Aurora Store pulls the exact APK from Play Store servers, so Aurora users get whichever variant was uploaded. The Play Store AAB built with -PfirebaseEnabled is correct for Aurora.

F-Droid is stricter: their build policy rejects any APK with GMS dependencies at the binary level, even with graceful degradation. F-Droid submission would require a separate assembleRelease build (no flag) and a dedicated F-Droid listing.

The google-services.json file

  • Gitignored (android/.gitignore line 80) — never commit it
  • Contains Firebase project credentials (project number, app ID, API key)
  • Safe to leave on disk; has no effect unless -PfirebaseEnabled is passed
  • Obtain from the Firebase console: Project Settings → Your apps → Android app → Download google-services.json

Known GMS dependency: MLKit barcode scanner

@capacitor-mlkit/barcode-scanning unconditionally depends on com.google.android.gms:play-services-code-scanner (present since the plugin was first added at v6.0.0). This merges com.google.android.gms.version and GoogleApiActivity into the APK manifest regardless of the -PfirebaseEnabled flag.

Practical impact:

  • GMS devices: barcode scanning works normally
  • Non-GMS devices: barcode scanning fails at scan time (not at startup); the app launches and runs normally otherwise

This is an accepted trade-off. Removing it would require either forking the plugin or introducing a foss product flavor that excludes the MLKit plugin entirely — work to undertake if/when F-Droid submission is planned.

Incident: June 2026

Jose Olarte III's notify-api branch placed a production google-services.json in android/ to test Firebase Cloud Messaging. The branch was never merged to master, but because the file is gitignored it persisted on disk after switching branches. At the time, the Gradle conditional activated Firebase based on file presence alone (no opt-in flag), so all subsequent local builds embedded Firebase and required Google Play Services. This silently broke APK/Aurora/Zapstore distribution.

Fix applied: deleted google-services.json from disk, changed the Gradle conditional to require -PfirebaseEnabled, and documented the rule in AGENTS.md.