What Are Push Notifications?
Push notifications are messages sent from a server to a user's device, displayed even when the app is not actively running. They are one of the most powerful tools for user engagement, re-engagement, and real-time communication in mobile apps.
When done well, push notifications drive retention and keep users informed. When done poorly, they drive uninstalls.
How Push Notifications Work
The flow involves three parties: your backend server, a platform notification service, and the user's device.
iOS (APNs)
- Your app requests permission from the user
- If granted, the app registers with Apple Push Notification service (APNs) and receives a device token
- Your app sends this token to your backend
- When you want to send a notification, your backend sends a payload to APNs with the device token
- APNs delivers the notification to the device
Android (FCM)
- Your app initializes Firebase Cloud Messaging (FCM) and receives a registration token
- Your app sends this token to your backend
- Your backend sends a payload to FCM with the token
- FCM delivers the notification to the device
Android does not require explicit user permission for basic notifications (prior to Android 13). Starting with Android 13 (API 33), apps must request the POST_NOTIFICATIONS runtime permission.
Permission Strategies
iOS Permission Prompt
iOS shows a system dialog asking the user to allow notifications. You get one chance to show this prompt. If the user declines, they must manually enable notifications in Settings.
Best practices for the permission prompt:
- Do not ask on first launch. Wait until the user understands the app's value.
- Pre-prompt first. Show your own in-app screen explaining why notifications are useful before triggering the system dialog.
- Context matters. Ask at a moment when the notification value is clear (e.g., after the user creates an order and would want status updates).
Android 13+ Permission
Similar to iOS, but you can check if the user has previously denied the permission and adjust your approach accordingly. The system dialog behaves like any other runtime permission.
Notification Payloads
Basic Structure
A push notification payload typically includes:
- title: The bold heading
- body: The message text
- data: Custom key-value pairs for your app to process (invisible to user)
- badge: The number shown on the app icon (iOS)
- sound: Custom or default notification sound
- image: A rich notification with an image attachment
Silent Notifications
Both platforms support silent (background) notifications that wake your app without showing anything to the user. These are useful for background data sync, content pre-fetching, or triggering local notifications based on server-side logic.
Rich Notifications
iOS (Notification Service Extension)
You can intercept and modify notifications before they are displayed. Common uses:
- Download and attach images
- Decrypt encrypted payloads
- Modify the notification content based on app state
Notification Content Extensions allow custom UI in the expanded notification view (interactive buttons, media playback, etc.).
Android (Custom Notification Channels)
Android uses notification channels (since Android 8) to give users granular control:
- Group notifications by type (messages, promotions, updates)
- Users can customize sound, vibration, and importance per channel
- Your app should create channels during initialization
Cross-Platform Implementation
Expo Notifications
expo-notifications provides a unified API for both platforms. It handles token registration, permission requests, notification listeners, and local notification scheduling. Combined with EAS, you can configure APNs credentials and FCM keys without touching native code.
React Native (bare)
Use @react-native-firebase/messaging for FCM and handle APNs through the same library (FCM wraps APNs on iOS by default).
Flutter
The firebase_messaging package handles both platforms. Combined with flutter_local_notifications for rich local notification display.
Backend Considerations
Your backend needs to:
- Store device tokens mapped to user accounts
- Handle token refresh (tokens change periodically)
- Remove invalid tokens when the push service reports errors
- Support topic-based or segment-based sending for broadcasts
- Rate-limit notifications to avoid spamming users
Popular services: Firebase Cloud Messaging (free), Amazon SNS, OneSignal, Pusher, or build your own with direct APNs/FCM API calls.
Engagement Best Practices
- Personalize: Use the user's name and relevant context
- Time it right: Send at times when the user is typically active
- Be valuable: Every notification should provide clear value
- Allow preferences: Let users choose which notification types they receive in-app
- Measure: Track open rates, dismissal rates, and uninstall correlation
- Do not overdo it: 3-5 notifications per week is a common sweet spot