Working with Notifications
1. Setting Up Push Notifications
Example: Configuring Push Notifications in React Native
import PushNotification from 'react-native-push-notification';
PushNotification.configure({
onRegister: function (token) {
console.log('TOKEN:', token);
},
onNotification: function (notification) {
console.log('NOTIFICATION:', notification);
},
permissions: {
alert: true,
badge: true,
sound: true
},
popInitialNotification: true,
requestPermissions: true
});
| Property | Description | Default Value |
|---|---|---|
| onRegister | Callback function when device token is received | null |
| onNotification | Callback function when notification is received | null |
| permissions | Permissions for notifications (alert, badge, sound) | { alert: true, badge: true, sound: true } |
| popInitialNotification | Whether to pop initial notification if app was closed | true |
| requestPermissions | Whether to request permissions automatically | true |
Note: For iOS, you must also configure the
Info.plist to enable push notifications.
Warning: On Android, ensure that you have added the necessary permissions in
AndroidManifest.xml.
2. Requesting Notification Permissions
| Permission | Description | Status |
|---|---|---|
| notifications | Allows the app to display notifications to the user. | NEW |
Example: Requesting Notification Permissions
import { PermissionsAndroid, Platform } from 'react-native';
const requestNotificationPermission = async () => {
if (Platform.OS === 'android') {
try {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS,
{
title: 'Notification Permission',
message: 'This app wants to show notifications.',
buttonNeutral: 'Ask Me Later',
buttonNegative: 'Cancel',
buttonPositive: 'OK'
}
);
if (granted === PermissionsAndroid.RESULTS.GRANTED) {
console.log('Notification permission granted');
} else {
console.log('Notification permission denied');
}
} catch (err) {
console.warn(err);
}
}
};
Note: On iOS, notification permissions are requested automatically when you register for remote notifications.
3. Handling Notification Events
Example: Setting up notification event handlers
import { Notifications } from 'expo-notifications';
// Handle notification received while app is in foreground
Notifications.addNotificationReceivedListener(notification => {
console.log('Notification received:', notification);
});
// Handle notification tapped by user
Notifications.addNotificationResponseReceivedListener(response => {
console.log('Notification response:', response);
const { notification, actionIdentifier } = response;
if (actionIdentifier === 'OPEN_APP') {
// Navigate to specific screen
}
});
| Event Type | Description | Callback Parameters |
|---|---|---|
| notificationReceived | Triggered when a notification is received while the app is in the foreground | notification: Notification |
| notificationResponseReceived | Triggered when a notification is tapped or action is performed | response: NotificationResponse |
Note: These listeners are automatically cleaned up when the app is closed, but it's good practice to remove them manually if needed.
4. Displaying Local Notifications
| Property | Description | Example |
|---|---|---|
| title | Title of the notification | "New Message" |
| body | Body text of the notification | "You have a new message from John" |
| sound | Sound to play when notification is shown | "default" |
| badge | Badge number to display on app icon | 1 |
| actions | Actions to show with notification | [{ title: "Reply", id: "reply" }] |
Example: Displaying a Local Notification
import PushNotification from "react-native-push-notification";
PushNotification.localNotification({
title: "New Message",
message: "You have a new message from John",
sound: "default",
badge: 1,
actions: [{ title: "Reply", id: "reply" }]
});
Note: Ensure that you have requested notification permissions before displaying local notifications.
5. Handling Notification Actions
| Action | Description | Platform Support |
|---|---|---|
| action | Identifier for the action button | iOS, Android |
| title | Text displayed on the action button | iOS, Android |
| icon | Icon resource for the action (Android) | Android |
| color | Color of the action button (Android) | Android |
Example: Handling Notification Actions
import { Notifications } from 'expo-notifications';
Notifications.setNotificationHandler({
handleNotification: async (notification) => {
return {
shouldShowAlert: true,
shouldPlaySound: true,
shouldSetBadge: false,
};
},
});
// Register for action taps
Notifications.addNotificationResponseReceivedListener(response => {
const { action, data } = response;
console.log('Action tapped:', action);
if (action === 'open') {
// Handle open action
} else if (action === 'dismiss') {
// Handle dismiss action
}
});
Note: On Android, actions must be registered with
Notifications.setNotificationChannelAsync before they can be used.
Workflow: Setting Up Notification Actions
- Create a notification channel with actions (Android)
- Define action identifiers and titles
- Register a listener for notification responses
- Handle actions in the response callback
6. Using Notification Badges
| Property | Description | Values |
|---|---|---|
| badge | Specifies the badge number to display on the notification | number |
| badgeColor | Background color of the badge (iOS only) | string |
Example: Setting a Badge Number
import { Notifications } from 'react-native-notifications';
Notifications.postLocalNotification({
id: '1',
title: 'New Message',
body: 'You have a new message',
badge: 5,
badgeColor: '#FF0000'
});
Note: Badge numbers are supported on iOS and Android, but behavior may vary depending on the OS version and device settings.
7. Implementing Silent Notifications
| Property | Description | Values |
|---|---|---|
| silent | Indicates whether the notification should be silent | true or false |
Example: Silent Notification Configuration
import notifee from '@notifee/react-native';\n\nconst notification = {\n title: 'Silent Notification',\n body: 'This notification has no sound or vibration.',\n silent: true,\n};\n\nawait notifee.displayNotification(notification);
Note: Silent notifications are useful for background updates or status changes where audio or vibration is not required.
8. Handling Deep Links from Notifications
| Property | Description | Example |
|---|---|---|
| data | Data object passed with the notification, can include deep link info | { url: 'myapp://screen/123' } |
| action | Action string to identify the notification type | 'OPEN_DEEP_LINK' |
Example: Handling Deep Links in Notification
import { Platform } from 'react-native';
import { Notifications } from 'react-native-notifications';
Notifications.events().registerNotificationOpened((notification) => {
const { data } = notification.payload;
if (data && data.url) {
// Handle deep link navigation
console.log('Deep link URL:', data.url);
}
});
Note: Ensure your app handles deep links in the
notificationOpened event to navigate users correctly.
Warning: On iOS, deep links must be registered in
Info.plist under CFBundleURLTypes.
9. Scheduling Notifications
| Property | Description | Values | Notes |
|---|---|---|---|
| id | Unique identifier for the notification | string |
Required for scheduling |
| title | Title of the notification | string |
Display in notification center |
| body | Body content of the notification | string |
Optional but recommended |
| schedule | Scheduling configuration | object |
See below for details |
| sound | Sound to play when notification fires | string |
Defaults to system sound |
| badge | Badge count to display on app icon | number |
Only supported on iOS |
Example: Schedule a notification with delay
import PushNotification from 'react-native-push-notification';
PushNotification.localNotificationSchedule({
id: '123',
title: 'Reminder',
message: 'You have a meeting in 5 minutes',
date: new Date(Date.now() + 5 * 60 * 1000),
sound: 'default',
vibrate: true,
badge: 1
});
Example: Schedule a recurring notification
import PushNotification from 'react-native-push-notification';
PushNotification.localNotificationSchedule({
id: '456',
title: 'Daily Reminder',
message: 'Check your tasks for today',
repeatType: 'day',
date: new Date(Date.now() + 24 * 60 * 60 * 1000),
sound: 'default',
vibrate: true
});
Note: On Android, notifications must be scheduled with a minimum delay of 1 minute to comply with system restrictions.
10. Testing Notifications
Example: Mocking Notification Permissions
import { PermissionsAndroid, Platform } from 'react-native';
// Mock permissions for testing
jest.mock('react-native', () => {
const RN = jest.requireActual('react-native');
RN.PermissionsAndroid = {
check: jest.fn().mockResolvedValue(true),
request: jest.fn().mockResolvedValue(PermissionsAndroid.RESULTS.GRANTED),
};
return RN;
});
// Test notification permission request
test('requests notification permission on startup', async () => {
const { requestNotificationPermission } = require('./notificationService');
const result = await requestNotificationPermission();
expect(result).toBe('granted');
});
| Permission | Status | Description |
|---|---|---|
| android.permission.POST_NOTIFICATIONS | granted |
Required for sending notifications on Android 13+ |
| ios.permission.NOTIFICATIONS | authorized |
Required for displaying notifications on iOS |
Testing Workflow
- Mock native permissions using Jest
- Simulate permission grant/rejection scenarios
- Test notification delivery with different payloads
- Verify notification UI rendering in test environment
Note: On iOS, notifications must be registered with
requestPermissions before they can be delivered.
Warning: Android 13+ requires explicit permission for notifications. Testing should simulate this behavior.
11. Using Notifee Library
Example: Requesting Notification Permissions
import notifee from '@notifee/react-native';
const requestPermission = async () => {
const authStatus = await notifee.requestPermission();
console.log('Permission status:', authStatus);
};
| Property | Description | Values |
|---|---|---|
| requestPermission() | Requests notification permission from the user | Promise<PermissionStatus> |
| displayNotification() | Displays a local notification | Promise<void> |
| scheduleNotification() | Schedules a notification to be displayed at a specific time | Promise<void> |
Example: Displaying a Local Notification
import notifee from '@notifee/react-native';
const showNotification = async () => {
await notifee.displayNotification({
title: 'New Message',
body: 'You have a new message from John',
android: {
channelId: 'messages',
smallIcon: 'ic_notification',
},
});
};
Example: Scheduling a Notification
import notifee from '@notifee/react-native';
const scheduleNotification = async () => {
await notifee.scheduleNotification(
{
title: 'Reminder',
body: 'Don't forget your appointment!',
android: {
channelId: 'reminders',
},
},
{
at: new Date(Date.now() + 60 * 1000), // 1 minute from now
}
);
};
Note: Ensure that you have configured the necessary Android and iOS permissions in your app's manifest files.