mirror of
https://github.com/wu736139669/hapi.git
synced 2026-10-07 19:06:11 +00:00
Gradle/Firebase: firebase-messaging + work-runtime-ktx in the catalog and
:app; com.google.gms.google-services applied CONDITIONALLY (only when
app/google-services.json exists) so the repo builds green without any
Firebase config; committed google-services.json.example + README section
(CI-injected official builds / self-build drop-in / v1.x runtime
FirebaseOptions path); real config gitignored. push/PushBinding.kt is the
availability seam: no Firebase -> every push path no-ops.
Registration (:core:data push/DeviceRegistrar): stable DataStore UUID
deviceId; POST /api/devices/register {token, platform:'phone', deviceId}
fanned out to EVERY paired hub on app start, on pairing (roster addition),
and on onNewToken; transient failures retry via a per-hub WorkManager
unique work item; best-effort DELETE on sign-out while the hub's JWT still
works.
Service (fcm/HapiFirebaseMessagingService): data-only contract v1 decoding
in :core:data push/PushPayload — channels permission_requests(HIGH) /
ready / task_notifications (created on app start), type-<sessionId>
coalescing tags, severity accent colors, notifySummary-driven ready
bodies, unknown type/contractVersion degrade to plain title/body (default
channel, no actions). Suppress-when-open: foreground + that session's
chat composed -> skip (SSE already shows it). Tap -> internal MainActivity
intent route (no public URI) -> existing navigation opens the chat.
Actions: permission-request Allow/Deny and ready/task RemoteInput Reply +
Dismiss -> NotificationActionReceiver -> expedited CoroutineWorkers
(approve/deny {} bodies, reply {text, localId}) through on-demand
HubSessions built from stored credentials (HapiWorkerFactory +
Configuration.Provider + on-demand WorkManager init — no HubGraph needed
in background); notification updates pending -> done / "Already handled"
(404 request-gone) / inactive / failed. Multi-hub: payload has no hub URL,
so workers try the ACTIVE hub first, then other paired hubs on 404
session-miss (single-hub users always hit first try).
Hub check: android.priority=HIGH is already set unconditionally for every
FCM message (hub/src/fcm/fcmService.ts) — no hub change needed.
Tests (34 new, :core:data): payload keys/severities/unknown contract
version, channel routing, suppress-when-open; registrar fan-out /
addition-only / retry-on-transient / null-token no-op via fake seams;
action wire bodies + Bearer header + multi-hub resolution through a real
HubSession against two MockWebServers. Full gate green with AND without
google-services.json (protocol 227, data 182, app 96 tests; debug +
release/R8/lintVital assemble).
42 lines
1.4 KiB
JSON
42 lines
1.4 KiB
JSON
{
|
|
"_comment": [
|
|
"Placeholder Firebase config (B-M4a). To enable FCM push in a self-build:",
|
|
"1. Create a Firebase project (console.firebase.google.com) and add an",
|
|
" Android app with package name `run.hapi.companion` (or your fork's",
|
|
" applicationId — keep app/build.gradle.kts in sync).",
|
|
"2. Download the real google-services.json from the Firebase console and",
|
|
" save it as android/app/google-services.json (gitignored).",
|
|
"3. Configure the SAME Firebase project on your hub:",
|
|
" FCM_SERVICE_ACCOUNT_PATH + FCM_PROJECT_ID (docs/api/native-companion-contract.md).",
|
|
"Without the file the app still builds and runs — push is simply reported",
|
|
"unavailable (PushBinding) and every push code path no-ops."
|
|
],
|
|
"project_info": {
|
|
"project_number": "000000000000",
|
|
"project_id": "your-firebase-project-id",
|
|
"storage_bucket": "your-firebase-project-id.appspot.com"
|
|
},
|
|
"client": [
|
|
{
|
|
"client_info": {
|
|
"mobilesdk_app_id": "1:000000000000:android:0000000000000000000000",
|
|
"android_client_info": {
|
|
"package_name": "run.hapi.companion"
|
|
}
|
|
},
|
|
"oauth_client": [],
|
|
"api_key": [
|
|
{
|
|
"current_key": "AIzaSy-your-android-api-key"
|
|
}
|
|
],
|
|
"services": {
|
|
"appinvite_service": {
|
|
"other_platform_oauth_client": []
|
|
}
|
|
}
|
|
}
|
|
],
|
|
"configuration_version": "1"
|
|
}
|