67 lines
3.9 KiB
Markdown
67 lines
3.9 KiB
Markdown
# 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`.
|