Push Notifications
What This Does
Sets up push notification infrastructure for mobile applications — covering Firebase Cloud Messaging (FCM), Apple Push Notification service (APNs), and third-party providers like OneSignal. Includes rich notifications, notification channels, user segmentation, and engagement best practices.
Instructions
Choose your notification provider.
| Provider |
Best For |
Cost |
| FCM (Firebase) |
Android-first, direct Google integration |
Free |
| APNs (direct) |
iOS-only apps, maximum control |
Free |
| OneSignal |
Cross-platform, no backend needed |
Free tier, paid for scale |
| Expo Notifications |
Expo React Native apps |
Free with Expo |
| Amazon SNS |
AWS-native infrastructure |
Pay per message |
Platform setup.
iOS (APNs):
- Enable Push Notifications capability in Xcode
- Generate APNs key (p8 file) in Apple Developer portal
- Configure key ID, team ID, and bundle ID in your backend/provider
- Request notification permission at an appropriate moment (not on first launch)
Android (FCM):
- Add
google-services.json to the Android project
- Create notification channels (Android 8+) for different notification types
- Handle both foreground and background message reception
- Configure default notification icon and color
Permission handling (critical for iOS):
// NEVER request permission on first launch
// DO request after the user has experienced value from the app
Strategy:
1. User completes a key action (first purchase, first save, etc.)
2. Show a pre-permission screen explaining WHY notifications help
3. If user agrees, show the system permission dialog
4. If denied, gracefully handle — don't nag
Timing matters: apps that request permission after demonstrating value see 2-3x higher opt-in rates than apps that ask on first launch.
Notification payload structure:
{
"notification": {
"title": "Your order is ready!",
"body": "Pick up your coffee at the counter.",
"image": "https://example.com/coffee.jpg"
},
"data": {
"type": "order_ready",
"orderId": "abc-123",
"deepLink": "myapp://orders/abc-123"
},
"android": {
"notification": {
"channel_id": "orders",
"priority": "high",
"click_action": "OPEN_ORDER"
}
},
"apns": {
"payload": {
"aps": {
"category": "ORDER_ACTIONS",
"mutable-content": 1,
"sound": "default"
}
}
}
}
Rich notifications. Go beyond plain text:
- Images: Attach product images, maps, or previews
- Action buttons: "Accept" / "Decline," "Reply," "Mark as Read"
- Interactive: Live Activities (iOS), ongoing notifications (Android)
- Grouped: Thread notifications by conversation or category
Notification channels (Android 8+):
// Create channels at app startup
val channels = listOf(
NotificationChannel("orders", "Orders", NotificationManager.IMPORTANCE_HIGH),
NotificationChannel("promotions", "Promotions", NotificationManager.IMPORTANCE_DEFAULT),
NotificationChannel("social", "Social", NotificationManager.IMPORTANCE_LOW),
)
channels.forEach { channel ->
notificationManager.createNotificationChannel(channel)
}
Users can independently mute channels — respect this by categorizing notifications properly.
Backend integration. Send notifications from your server:
- Store device tokens securely (encrypt at rest)
- Handle token refresh (tokens change periodically)
- Implement retry logic for failed deliveries
- Track delivery status (sent, delivered, opened)
- Clean up invalid tokens (FCM returns canonical IDs, APNs returns errors)
Engagement best practices:
- Personalize: use the user's name and relevant context
- Timing: send during the user's active hours (track timezone)
- Frequency: 2-5 per week max for most apps — more causes uninstalls
- Value: every notification should provide clear value to the user
- Segmentation: different messages for different user cohorts
- A/B test: try different copy, timing, and CTAs
Output Format
# Push Notification Setup: {App Name}
## Provider: {FCM / APNs / OneSignal / etc.}
## Platform Configuration
### iOS
- APNs Key: {setup steps}
- Permission flow: {when and how to request}
### Android
- FCM Config: {setup steps}
- Channels: {list of channels and importance levels}
## Notification Types
| Type | Channel | Priority | Content |
|------|---------|----------|---------|
| {type} | {channel} | {H/M/L} | {description} |
## Backend Integration
{API endpoints or service configuration for sending notifications}
## Engagement Rules
{Frequency caps, timing windows, segmentation strategy}
Tips
- Always include a deep link in the notification data payload — don't just open the app home screen
- iOS: use Notification Service Extension for image attachments and end-to-end encryption
- Android: use
priority: high for time-sensitive notifications, priority: normal for everything else
- Test notifications on real devices — simulators have limited notification support
- Track opt-in rates, open rates, and uninstall rates correlated with notification frequency
- Implement notification preferences in your app — let users choose what they receive
- Silent/background notifications are powerful for data sync but drain battery — use sparingly
1---2name: push-notifications3description: Push notification setup and best practices — FCM, APNs, OneSignal, rich notifications, and engagement optimization.4---56# Push Notifications78## What This Does910Sets up push notification infrastructure for mobile applications — covering Firebase Cloud Messaging (FCM), Apple Push Notification service (APNs), and third-party providers like OneSignal. Includes rich notifications, notification channels, user segmentation, and engagement best practices.1112## Instructions13141. **Choose your notification provider.**1516 | Provider | Best For | Cost |17 |----------|----------|------|18 | FCM (Firebase) | Android-first, direct Google integration | Free |19 | APNs (direct) | iOS-only apps, maximum control | Free |20 | OneSignal | Cross-platform, no backend needed | Free tier, paid for scale |21 | Expo Notifications | Expo React Native apps | Free with Expo |22 | Amazon SNS | AWS-native infrastructure | Pay per message |23242. **Platform setup.**2526 **iOS (APNs):**27 - Enable Push Notifications capability in Xcode28 - Generate APNs key (p8 file) in Apple Developer portal29 - Configure key ID, team ID, and bundle ID in your backend/provider30 - Request notification permission at an appropriate moment (not on first launch)3132 **Android (FCM):**33 - Add `google-services.json` to the Android project34 - Create notification channels (Android 8+) for different notification types35 - Handle both foreground and background message reception36 - Configure default notification icon and color37383. **Permission handling (critical for iOS):**39 ```40 // NEVER request permission on first launch41 // DO request after the user has experienced value from the app4243 Strategy:44 1. User completes a key action (first purchase, first save, etc.)45 2. Show a pre-permission screen explaining WHY notifications help46 3. If user agrees, show the system permission dialog47 4. If denied, gracefully handle — don't nag48 ```4950 Timing matters: apps that request permission after demonstrating value see 2-3x higher opt-in rates than apps that ask on first launch.51524. **Notification payload structure:**53 ```json54 {55 "notification": {56 "title": "Your order is ready!",57 "body": "Pick up your coffee at the counter.",58 "image": "https://example.com/coffee.jpg"59 },60 "data": {61 "type": "order_ready",62 "orderId": "abc-123",63 "deepLink": "myapp://orders/abc-123"64 },65 "android": {66 "notification": {67 "channel_id": "orders",68 "priority": "high",69 "click_action": "OPEN_ORDER"70 }71 },72 "apns": {73 "payload": {74 "aps": {75 "category": "ORDER_ACTIONS",76 "mutable-content": 1,77 "sound": "default"78 }79 }80 }81 }82 ```83845. **Rich notifications.** Go beyond plain text:85 - **Images:** Attach product images, maps, or previews86 - **Action buttons:** "Accept" / "Decline," "Reply," "Mark as Read"87 - **Interactive:** Live Activities (iOS), ongoing notifications (Android)88 - **Grouped:** Thread notifications by conversation or category89906. **Notification channels (Android 8+):**91 ```kotlin92 // Create channels at app startup93 val channels = listOf(94 NotificationChannel("orders", "Orders", NotificationManager.IMPORTANCE_HIGH),95 NotificationChannel("promotions", "Promotions", NotificationManager.IMPORTANCE_DEFAULT),96 NotificationChannel("social", "Social", NotificationManager.IMPORTANCE_LOW),97 )9899 channels.forEach { channel ->100 notificationManager.createNotificationChannel(channel)101 }102 ```103104 Users can independently mute channels — respect this by categorizing notifications properly.1051067. **Backend integration.** Send notifications from your server:107 - Store device tokens securely (encrypt at rest)108 - Handle token refresh (tokens change periodically)109 - Implement retry logic for failed deliveries110 - Track delivery status (sent, delivered, opened)111 - Clean up invalid tokens (FCM returns canonical IDs, APNs returns errors)1121138. **Engagement best practices:**114 - Personalize: use the user's name and relevant context115 - Timing: send during the user's active hours (track timezone)116 - Frequency: 2-5 per week max for most apps — more causes uninstalls117 - Value: every notification should provide clear value to the user118 - Segmentation: different messages for different user cohorts119 - A/B test: try different copy, timing, and CTAs120121## Output Format122123```markdown124# Push Notification Setup: {App Name}125126## Provider: {FCM / APNs / OneSignal / etc.}127128## Platform Configuration129### iOS130- APNs Key: {setup steps}131- Permission flow: {when and how to request}132133### Android134- FCM Config: {setup steps}135- Channels: {list of channels and importance levels}136137## Notification Types138| Type | Channel | Priority | Content |139|------|---------|----------|---------|140| {type} | {channel} | {H/M/L} | {description} |141142## Backend Integration143{API endpoints or service configuration for sending notifications}144145## Engagement Rules146{Frequency caps, timing windows, segmentation strategy}147```148149## Tips150151- Always include a deep link in the notification data payload — don't just open the app home screen152- iOS: use Notification Service Extension for image attachments and end-to-end encryption153- Android: use `priority: high` for time-sensitive notifications, `priority: normal` for everything else154- Test notifications on real devices — simulators have limited notification support155- Track opt-in rates, open rates, and uninstall rates correlated with notification frequency156- Implement notification preferences in your app — let users choose what they receive157- Silent/background notifications are powerful for data sync but drain battery — use sparingly