make a fix for running in an emulator, plus doc changes

This commit is contained in:
2026-09-27 21:17:36 -06:00
parent 2fd5549098
commit 4bb0e4d4f9
4 changed files with 34 additions and 11 deletions
+1 -1
View File
@@ -13,7 +13,7 @@ This guard is in `android/app/build.gradle`. Do NOT change this conditional to a
`google-services.json` is intentionally excluded from git (`android/.gitignore`). Never commit it.
Full details, incident history, and F-Droid notes: `doc/development/android-firebase-gms.md`
Full details, incident history, and F-Droid notes: `doc/android-firebase-gms.md`
## Android Build — MLKit Barcode Scanner
+5 -9
View File
@@ -1329,6 +1329,7 @@ npm run build:android:prod # Production build (builds for production e
# Auto-run builds
npm run build:android:test:run # Test build with auto-run (builds then runs on emulator)
npm run build:android:prod:run # Production build with auto-run (builds then runs on emulator)
# Auto-run targets the one connected device; with none or several it prompts, or exits 9 without a terminal
# Debug and release builds
npm run build:android:debug # Debug build (builds debug APK)
@@ -1454,20 +1455,15 @@ npx cap open android
#### Android Build from the console
```bash
cd android
./gradlew clean
./gradlew build -Dlint.baselines.continue=true
cd -
```
* Note that this currently fails: `./gradlew build -Dlint.baselines.continue=true`
... or, to create the `aab` file, `bundle` instead of `build` (but not signed and not usable in Play Store):
To create the `aab` file, `bundle` instead of `build` (but not signed and not usable in Play Store):
```bash
./gradlew bundleDebug -Dlint.baselines.continue=true
```
... or, to create a signed `aab` release:
So, to create a signed `aab` release:
- Setup by adding the app/gradle.properties.secrets file (see properties at top
of app/build.gradle) and the app/time-safari-upload-key-pkcs12.jks file
@@ -1843,7 +1839,7 @@ npm run build:android:assets
- Configure signing keys
- Check device/emulator setup
## Additional Resources
## Additional Documentation
- [Electron Build Patterns](doc/electron-build-patterns.md)
- [iOS Build Scripts](doc/ios-build-scripts.md)
+16
View File
@@ -42,6 +42,16 @@ This means a single Play Store AAB (`bundleRelease -PfirebaseEnabled`) covers bo
**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.
## Push registration in builds without Firebase
A build without `-PfirebaseEnabled` contains the `@capacitor/push-notifications` plugin, but no Firebase config. In that build, `PushNotifications.register()` throws `Default FirebaseApp is not initialized` on the Capacitor plugin thread, which kills the app; a JS `try/catch` cannot intercept it.
The JS therefore asks native code first. `NotificationInspector.isFirebaseConfigured()` (`android/app/src/main/java/app/timesafari/notifications/NotificationInspectorPlugin.java`) reports whether the `google_app_id` string resource exists; the google-services Gradle plugin generates that resource only when Firebase is enabled, and it is the same signal Firebase's auto-initialization uses. `firebaseMessagingClient.ts` skips `register()` on Android when it is absent (or when the check fails), logging `No Firebase config in this Android build; skipping push registration`. Listener setup and the notification permission request run either way, since local daily notifications need that permission.
`NotificationInspector` must be listed in `scripts/restore-local-plugins.js`: `MainActivity` registers plugins after the Capacitor bridge is built, so a plugin missing from `capacitor.plugins.json` reports "not implemented on android" and the check falls back to skipping push.
Any code that calls `PushNotifications.register()` or other `FirebaseMessaging` APIs on Android must go through the same check.
## The `google-services.json` file
- Gitignored (`android/.gitignore` line 80) — never commit it
@@ -64,3 +74,9 @@ This is an accepted trade-off. Removing it would require either forking the plug
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`.
## Incident: September 2026
After the June fix, local builds without `-PfirebaseEnabled` (including every `scripts/build-android.sh` build and the FOSS APKs from v1.4.4 on) crashed at launch as soon as notification permission was granted, because startup code called `PushNotifications.register()` unconditionally. Found while running `npm run build:android:prod:run` on an emulator.
**Fix applied:** the `isFirebaseConfigured()` gate described in "Push registration in builds without Firebase", plus adding `NotificationInspector` to `scripts/restore-local-plugins.js` so the check is reachable on Android.
+12 -1
View File
@@ -658,7 +658,18 @@ fi
# we already synced and ran restore-local-plugins.js above, so skip sync here.
if [ "$AUTO_RUN" = true ]; then
log_step "Auto-running Android app..."
safe_execute "Launching app" "npx cap run android --no-sync" || {
# With exactly one connected device, target it directly. Otherwise cap run
# shows an interactive picker, which without a terminal exits 0 having
# launched nothing, so fail instead of reporting a false success.
run_devices=$(adb devices | awk 'NR > 1 && $2 == "device" { print $1 }')
run_target=""
if [ "$(printf '%s\n' "$run_devices" | grep -c .)" = "1" ]; then
run_target="--target $run_devices"
elif [ ! -t 0 ]; then
log_error "Auto-run needs exactly one connected device when not run from a terminal (found: ${run_devices:-none})"
exit 9
fi
safe_execute "Launching app" "npx cap run android --no-sync $run_target" || {
log_error "Failed to launch Android app"
log_info "You can manually run with: npx cap run android --no-sync"
exit 9