Skip to content

feat: migration of APNS to FCM for IOS messages - #89

Merged
code-lucasgabriel merged 7 commits into
masterfrom
feat/migration-apns-to-fcm
May 14, 2026
Merged

feat: migration of APNS to FCM for IOS messages#89
code-lucasgabriel merged 7 commits into
masterfrom
feat/migration-apns-to-fcm

Conversation

@code-lucasgabriel

Copy link
Copy Markdown
Collaborator

Adds iOS push-notification support to the GCM/Firebase pusher so iOS messages can be delivered via FCM instead of the legacy APNS code path. The migration is staged across three commits so each step is independently reviewable and the final state is non-breaking until upstream producers start writing to the new topics.

What changes

  1. Ingest iOS via new FCM Kafka topics (d78859e)
  • Extend the queue topic regex (config/default.yaml, config/test.yaml, extensions/common.go) to also match ios, producing the pattern ^push-[\w]+(?:[-][\w]+)*(apns|gcm|ios)-(single|massive).
  • Add Platform to interfaces.KafkaMessage and populate it from the topic in extensions/kafka_consumer.go.
  • Subscribe the gcm pusher to push-_ios-(single|massive) for every configured app (pusher/gcm.go).
  • Unit tests for the new parsing and consumer behavior.
  1. Thread platform through the Firebase message handler (526880f)
  • Add Platform to interfaces.Message and resolve it (gcm or ios, defaulting to gcm when empty) at the top of HandleMessages.
  • Replace hardcoded "gcm" strings with the resolved platform across dedup, rate limiting, the duplicate-detected stat, sendPush, HandleResponses, and every feedback/stats reporter call - so iOS messages are tagged correctly in metrics and feedback.
  • Still non-breaking at this point: the Firebase client continues producing Android-style payloads regardless of platform.
  1. Build an APNS payload for iOS messages (cbd31ee)
  • toFirebaseMessage branches on Message.Platform: "ios" routes to a new buildIOSMessage, everything else keeps the existing Android logic.
  • buildIOSMessage builds a messaging.APNSConfig with apns-collapse-id, apns-priority, and apns-expiration headers when the corresponding Message fields are set, plus an Aps payload covering alert title/body/loc-keys/loc-args, sound, badge (parsed string→int, silently dropped if non-numeric), and content-available for silent pushes.

Compatibility & rollout

  • Backward-compatible by construction: messages without a Platform field (or coming off legacy topics) fall back to gcm and still build an Android payload, so existing Android traffic is unaffected.
  • The legacy pusher apns command is untouched: APNS-direct delivery keeps working during the transition.
  • Once this is deployed, the upstream sender service can start writing iOS messages to push-_ios-(single|massive) to migrate traffic off the direct-APNS path. Until that happens, the new topics are simply unused.

code-lucasgabriel and others added 6 commits April 28, 2026 13:54
Add ingestion for the new push-<game>_ios-(single|massive) topics so
the GCM pusher can consume iOS messages alongside the existing Android
ones.

- Extend topic regex in config and common.go to match the ios platform
- Add Platform field to KafkaMessage and populate it from the topic
- Subscribe pusher gcm to ios single/massive topics for every gcm app
- Cover new parsing and consumer behavior with unit tests
…tion

feat: ingest iOS push notifications via FCM Kafka topics
Adds a Platform field to interfaces.Message and resolves the platform
("gcm" or "ios", with empty string falling back to "gcm") from
KafkaMessage.Platform at the top of HandleMessages. The resolved value
is threaded through dedup, rate limiting, the duplicate-detected stat,
sendPush, HandleResponses, and every feedback/stats reporter call —
replacing the hardcoded "gcm" literals so iOS messages are tagged
correctly across observability paths.

The Firebase client still produces Android-style payloads, so this is
non-breaking until upstream services start publishing on _ios-* topics.
…-handler

feat(firebase): thread platform through message handler
toFirebaseMessage branches on Message.Platform: "ios" routes to
buildIOSMessage, anything else (including the empty default) keeps the
existing Android logic via buildAndroidMessage.

buildIOSMessage produces a messaging.APNSConfig with apns-collapse-id,
apns-priority and apns-expiration headers (when the corresponding
Message fields are set), and an Aps payload covering alert
title/body/loc-keys/loc-args, sound, badge (parsed from string to int,
silently dropped if not numeric) and content-available for silent
pushes.
feat(firebase): build APNS payload for iOS messages
Comment thread extensions/firebase/client/firebase.go
Per Apple's APNs spec, every request should declare apns-push-type so
APNs can route and validate it. The value must match the payload:
"background" for silent (content-available-only) pushes, "alert"
otherwise. Background pushes also force apns-priority to 5, since APNs
rejects background pushes sent with priority 10.
@code-lucasgabriel
code-lucasgabriel merged commit 36dc550 into master May 14, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants