Push Notifications
Implement push notifications for iOS and Android: APNs, FCM, rich notifications, notification grouping, and delivery optimization.
Push notifications are the primary re-engagement mechanism for mobile apps. Effective push implementation requires understanding the APNs (Apple) and FCM (Firebase/Google) delivery pipelines, notification permissions, rich notification content, and delivery optimization to maximize engagement without triggering opt-outs.
Request notification permission at a meaningful moment (not on app launch). Send fewer, higher-quality notifications. Personalize content. A/B test timing and copy. Measure opt-out rate as your primary push health metric - a rising opt-out rate is a sign of notification fatigue.
Workflow
- Set up APNs (iOS) with HTTP/2APNs token-based auth (HTTP/2) is simpler than certificates and doesn't expire.
- Set up FCM for Android and cross-platformFCM (Firebase Cloud Messaging) serves Android natively and can also deliver to iOS via APNs relay.
- Implement rich notificationsRich notifications (images, action buttons) have 3× higher engagement than plain text.
- Request permission at the right momentShowing the permission dialog on first launch results in 40-60% denial; contextual requests get 70%+ acceptance.
- Optimize delivery and engagementPoorly timed or irrelevant notifications drive opt-outs, which are permanent.
Output Format
APNs token auth setup, FCM multicast, rich notification with images+actions, permission request at meaningful moment, delivery analytics tracked.
Examples
FCM send: `await admin.messaging().send({ token: userToken, notification: { title: "Order shipped! 📦", body: "Your order #1234 is on its way" }, data: { orderId: "1234", screen: "order_tracking" }, android: { priority: "high" } })`iOS rich notification: `// In NotificationServiceExtension:
if let imageURL = bestAttempt?.request.content.userInfo["image_url"] as? String { let attachment = try UNNotificationAttachment(identifier: "image", url: URL(string: imageURL)!); bestAttempt?.attachments = [attachment] }`Permission timing: `func showOrderConfirmation() { presentOrderSuccess(); DispatchQueue.main.asyncAfter(deadline: .now() + 2) { self.requestNotificationsPermission() } }`Edge Cases & Gotchas
- Silent notifications (background refresh): limited to 3 per hour by iOS; don't rely on them for critical data updates
- Device token rotation: APNs rotates tokens periodically; always update your server with the new token in `application(_:didRegisterForRemoteNotificationsWithDeviceToken:)`
- Notification coalescing: if the user is offline, deliver only the latest notification per `apns-collapse-id` (iOS) or `collapseKey` (FCM) to avoid flooding
When to Break These Rules
- For transactional notifications (receipts, OTPs), use SMS as the primary channel - SMS has near-100% delivery vs push notifications' 70-90%.
Reference Files
APNs docs: https://developer.apple.com/documentation/usernotificationsFCM docs: https://firebase.google.com/docs/cloud-messagingNotification best practices: https://developer.apple.com/design/human-interface-guidelines/notifications