This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.
Handle incoming notifications
Edit page
Learn how to respond to a notification received by your app and take action based on the event.
The expo-notifications library contains event listeners that handle how your app responds when receiving a notification.
Notification event listeners
The addNotificationReceivedListener and addNotificationResponseReceivedListener event listeners receive an object when a notification is received or interacted with.
These listeners allow you to add behavior when notifications are received while your app is open and foregrounded and when your app is backgrounded or closed and the user taps on the notification.
useEffect(() => { registerForPushNotificationsAsync().then(token => setExpoPushToken(token)); const notificationListener = Notifications.addNotificationReceivedListener(notification => { console.log(notification); }); const responseListener = Notifications.addNotificationResponseReceivedListener(response => { console.log(response); }); return () => { notificationListener.remove(); responseListener.remove(); }; }, []);
Android notification object example from addNotificationReceivedListener
Sample of the notification object received by the callback function when using Notifications.addNotificationReceivedListener:
// console.log(notification); { "request": { "trigger": { "remoteMessage": { "originalPriority": 2, "sentTime": 1724782348210, "notification": { "usesDefaultVibrateSettings": false, "color": null, "channelId": null, "visibility": null, "sound": null, "tag": null, "bodyLocalizationArgs": null, "imageUrl": null, "title": "Chat App", "ticker": null, "eventTime": null, "body": "New message from John Doe", "titleLocalizationKey": null, "notificationPriority": null, "icon": null, "usesDefaultLightSettings": false, "sticky": false, "link": null, "titleLocalizationArgs": null, "bodyLocalizationKey": null, "usesDefaultSound": false, "clickAction": null, "localOnly": false, "lightSettings": null, "notificationCount": null }, "data": { "channelId": "default", "message": "New message from John Doe", "title": "Chat App", "body": "{\"senderId\":\"user123\",\"senderName\":\"John Doe\",\"messageId\":\"msg789\",\"conversationId\":\"conversation-456\",\"messageType\":\"text\",\"timestamp\":1724766427}", "scopeKey": "@betoatexpo/expo-notifications-app", "experienceId": "@betoatexpo/expo-notifications-app", "projectId": "51092087-87a4-4b12-8008-145625477434" }, "to": null, "ttl": 0, "collapseKey": "dev.expo.notificationsapp", "messageType": null, "priority": 2, "from": "115310547649", "messageId": "0:1724782348220771%0f02879c0f02879c" }, "channelId": "default", "type": "push" }, "content": { "autoDismiss": true, "title": "Chat App", "badge": null, "sticky": false, "sound": "default", "body": "New message from John Doe", "subtitle": null, "data": { "senderId": "user123", "senderName": "John Doe", "messageId": "msg789", "conversationId": "conversation-456", "messageType": "text", "timestamp": 1724766427 } }, "identifier": "0:1724782348220771%0f02879c0f02879c" }, "date": 1724782348210 }
You can directly access the notification custom data by logging the notification.request.content.data object:
// console.log(notification.request.content.data); { "senderId": "user123", "senderName": "John Doe", "messageId": "msg789", "conversationId": "conversation-456", "messageType": "text", "timestamp": 1724766427 }
iOS notification object example from addNotificationReceivedListener
Sample of the notification object received by the callback function when using Notifications.addNotificationReceivedListener:
// console.log(notification); { "request": { "trigger": { "class": "UNPushNotificationTrigger", "type": "push", "payload": { "experienceId": "@betoatexpo/expo-notifications-app", "projectId": "51092087-87a4-4b12-8008-145625477434", "scopeKey": "@betoatexpo/expo-notifications-app", "aps": { "thread-id": "", "category": "", "badge": 1, "alert": { "subtitle": "Hey there! How's your day going?", "title": "Chat App", "launch-image": "", "body": "New message from John Doe" }, "sound": "default" }, "body": { "messageId": "msg789", "timestamp": 1724766427, "messageType": "text", "senderId": "user123", "senderName": "John Doe", "conversationId": "conversation-456" } } }, "identifier": "3AEB849E-9059-4D09-BC3B-9A0B104CF062", "content": { "body": "New message from John Doe", "sound": "default", "launchImageName": "", "badge": 1, "subtitle": "Hey there! How's your day going?", "title": "Chat App", "data": { "conversationId": "conversation-456", "senderName": "John Doe", "senderId": "user123", "messageType": "text", "timestamp": 1724766427, "messageId": "msg789" }, "summaryArgument": null, "categoryIdentifier": "", "attachments": [], "interruptionLevel": "active", "threadIdentifier": "", "targetContentIdentifier": null, "summaryArgumentCount": 0 } }, "date": 1724798493.0589335 }
You can directly access the notification custom data by logging the notification.request.content.data object:
// console.log(notification.request.content.data); { "senderId": "user123", "senderName": "John Doe", "messageId": "msg789", "conversationId": "conversation-456", "messageType": "text", "timestamp": 1724766427 }
For more information on these objects, see Notification documentation.
Foreground notification behavior
In SDK 57 and earlier, a foreground notification is not shown at all by default. To show it, you have to set a handler that asks for it using Notifications.setNotificationHandler. A handler that does not respond within 3 seconds drops the notification.
In SDK 58 and later, a notification that arrives while your app is foregrounded is shown by default. It plays a sound, shows a banner, appears in the notification list, and sets the app badge. A notification whose handler does not respond within 3 seconds is shown the same way.
To change the behavior, use Notifications.setNotificationHandler with the handleNotification() callback to set the following options:
shouldPlaySoundshouldSetBadgeshouldShowBannershouldShowList
Notifications.setNotificationHandler({ handleNotification: async () => ({ shouldPlaySound: false, shouldSetBadge: false, shouldShowBanner: true, shouldShowList: true, }), });
Disable the notification handler
In SDK 58 and later, to stop expo-notifications from deciding whether an incoming notification shows, pass null:
Notifications.setNotificationHandler(null);
On Android, the notification is then not shown while your app is in the foreground. On iOS, the decision goes to the UNUserNotificationCenterDelegate that another library sets. If no library sets one, the notification is not shown.
Closed notification behavior
On Android, users can set certain OS-level settings, usually revolving around performance and battery optimization, that can prevent notifications from being delivered when the app is closed. For example, one such setting is the Deep Clear option on OnePlus devices using Android 9 and lower versions.