# 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 ```groovy 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`.