EPIC — FCM push activation. Broken into 5 dependency-ordered phases. Push is currently inactive; the app works fully over realtime chat, users just get no background notifications. Full runbook: docs/PUSH_SETUP.md.
Derived scope (from the iOS app)
Firebase for Android == FCM push only (iOS uses APNs directly; analytics is PostHog, crash is Sentry — no other Firebase surface). The event/payload contract is fixed and reused verbatim from send-push + iOS PushService:
- Events:
message, gig_request, booking_confirmed_client, booking_confirmed_artist, booking_reminder_24h, booking_review_request.
- Data keys:
artistant_event, artistant_thread_id, artistant_request_id, artistant_booking_id.
- The message preview is already server-redacted (
left(NEW.body,140), NEW.body redacted by the order-proofed BEFORE-INSERT trigger) → safe on a lockscreen; the anti-leakage moat holds with no client-side redaction.
- Transport: data-only FCM messages +
android.priority=high, so onMessageReceived fires foreground + background (client owns the channel, foreground-suppression, and routing).
- Schema change is additive:
device_tokens.fcm_token (nullable, unique) + apns_token becomes nullable + a one-token CHECK. iOS is unaffected (it selects explicit columns and always writes apns_token).
Phases
| Phase |
Issue |
Where |
Depends on |
P1 Backend — send-push FCM transport + device_tokens.fcm_token |
#37 |
cestercian/Artistant (iOS/Supabase) |
P3 for live delivery (merges inert) |
P2a Android — deep-link producer seam + channels + DeviceTokenRepository (no Firebase) |
#38 |
this repo |
— |
| P2b Android — Firebase Messaging + token lifecycle |
#39 |
this repo |
#38, #40 |
P3 Operator — Firebase project + google-services.json + FCM secrets |
#40 |
Firebase + Supabase dashboards |
— |
| P4 On-device verification + rollout |
#41 |
physical device |
#37, #39, #40 |
Dependency graph
P3 #40 (operator) ─┬─► P1 #37 (backend, live delivery)
└─► P2b #39 (build) ◄── P2a #38 (seam)
P1 #37 + P2b #39 + P3 #40 ─► P4 #41 (device verify) ─► close this epic
Critical path: P3 (operator, ~15 min) is the unblocker — both the backend (P1) and the Android Firebase code (P2b) can be written now but only go live once P3 lands. P2a has no blockers and can land immediately.
EPIC — FCM push activation. Broken into 5 dependency-ordered phases. Push is currently inactive; the app works fully over realtime chat, users just get no background notifications. Full runbook:
docs/PUSH_SETUP.md.Derived scope (from the iOS app)
Firebase for Android == FCM push only (iOS uses APNs directly; analytics is PostHog, crash is Sentry — no other Firebase surface). The event/payload contract is fixed and reused verbatim from
send-push+ iOSPushService:message,gig_request,booking_confirmed_client,booking_confirmed_artist,booking_reminder_24h,booking_review_request.artistant_event,artistant_thread_id,artistant_request_id,artistant_booking_id.left(NEW.body,140),NEW.bodyredacted by the order-proofed BEFORE-INSERT trigger) → safe on a lockscreen; the anti-leakage moat holds with no client-side redaction.android.priority=high, soonMessageReceivedfires foreground + background (client owns the channel, foreground-suppression, and routing).device_tokens.fcm_token(nullable, unique) +apns_tokenbecomes nullable + a one-token CHECK. iOS is unaffected (it selects explicit columns and always writesapns_token).Phases
send-pushFCM transport +device_tokens.fcm_tokencestercian/Artistant(iOS/Supabase)DeviceTokenRepository(no Firebase)google-services.json+ FCM secretsDependency graph
Critical path: P3 (operator, ~15 min) is the unblocker — both the backend (P1) and the Android Firebase code (P2b) can be written now but only go live once P3 lands. P2a has no blockers and can land immediately.