Push Notifications
Learn to implement push notifications in React Native applications for both iOS and Android platforms. This is a foundational concept in cross-platform mobile development that professional developers rely on daily. The explanations below are written to be beginner-friendly while covering the depth and nuance that comes from real-world React Native experience. Take your time with each section and practice the examples
Push Notifications Overview
Implement push notifications to engage users and provide real-time updates. Handle notification permissions, token registration, and notification handling.. This is an essential concept that every React Native developer must understand thoroughly. In professional development environments, getting this right can mean the difference between code that works reliably and code that breaks in production. The following sections break this down into clear, digestible pieces with practical examples you can try immediately
Notification Types
- Local notifications - Scheduled by the app — a critical concept in cross-platform mobile development that you will use frequently in real projects
- Remote notifications - Sent from server — a critical concept in cross-platform mobile development that you will use frequently in real projects
- Background notifications - When app is not active — a critical concept in cross-platform mobile development that you will use frequently in real projects
- Foreground notifications - When app is active — a critical concept in cross-platform mobile development that you will use frequently in real projects
Platform Differences
iOS and Android handle notifications differently. iOS requires APNs (Apple Push Notification service) while Android uses FCM (Firebase Cloud Messaging).. This is an essential concept that every React Native developer must understand thoroughly. In professional development environments, getting this right can mean the difference between code that works reliably and code that breaks in production. The following sections break this down into clear, digestible pieces with practical examples you can try immediately
Push Notifications Example
import React, { useState, useEffect } from 'react';
import {
View,
Text,
TouchableOpacity,
StyleSheet,
Alert,
Platform,
PermissionsAndroid
} from 'react-native';
import PushNotification from 'react-native-push-notification';
import messaging from '@react-native-firebase/messaging';
const PushNotifications = () => {
const [token, setToken] = useState(null);
const [permission, setPermission] = useState(null);
useEffect(() => {
// Request permission
requestPermission();
// Get FCM token
getToken();
// Listen for token refresh
const unsubscribeTokenRefresh = messaging().onTokenRefresh(token => {
setToken(token);
console.log('Token refreshed:', token);
});
// Listen for foreground messages
const unsubscribeForeground = messaging().onMessage(async remoteMessage => {
console.log('Foreground message:', remoteMessage);
Alert.alert(
remoteMessage.notification?.title || 'Notification',
remoteMessage.notification?.body || 'You have a new message'
);
});
// Listen for background/quit state messages
const unsubscribeBackground = messaging().setBackgroundMessageHandler(async remoteMessage => {
console.log('Background message:', remoteMessage);
});
// Configure local notifications
PushNotification.configure({
onRegister: function (token) {
console.log('TOKEN:', token);
setToken(token.token);
},
onNotification: function (notification) {
console.log('NOTIFICATION:', notification);
if (notification.userInteraction) {
// User tapped the notification
Alert.alert('Notification Tapped', notification.message || 'You tapped a notification');
}
},
permissions: {
alert: true,
badge: true,
sound: true,
},
popInitialNotification: true,
requestPermissions: Platform.OS === 'ios',
});
return () => {
unsubscribeTokenRefresh();
unsubscribeForeground();
};
}, []);
const requestPermission = async () => {
if (Platform.OS === 'android') {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS,
{
title: 'Notification Permission',
message: 'App needs permission to send notifications',
buttonNeutral: 'Ask Me Later',
buttonNegative: 'Cancel',
buttonPositive: 'OK',
}
);
setPermission(granted === PermissionsAndroid.RESULTS.GRANTED);
} else {
const authStatus = await messaging().requestPermission();
const enabled = authStatus === messaging.AuthorizationStatus.AUTHORIZED ||
authStatus === messaging.AuthorizationStatus.PROVISIONAL;
setPermission(enabled);
}
};
const getToken = async () => {
try {
const fcmToken = await messaging().getToken();
setToken(fcmToken);
console.log('FCM Token:', fcmToken);
} catch (error) {
console.log('Error getting token:', error);
}
};
const scheduleLocalNotification = () => {
PushNotification.localNotification({
title: 'Local Notification',
message: 'This is a local notification scheduled from the app',
playSound: true,
soundName: 'default',
actions: ['View', 'Dismiss'],
});
};
const scheduleDelayedNotification = () => {
PushNotification.localNotificationSchedule({
title: 'Delayed Notification',
message: 'This notification was scheduled 5 seconds ago',
date: new Date(Date.now() + 5000),
playSound: true,
soundName: 'default',
});
};
const cancelAllNotifications = () => {
PushNotification.cancelAllLocalNotifications();
Alert.alert('Success', 'All notifications cancelled');
};
const sendTestNotification = async () => {
if (!token) {
Alert.alert('Error', 'No FCM token available');
return;
}
// In a real app, you would send this to your server
// which would then send the notification via FCM
Alert.alert(
'Test Notification',
`Token: ${token.substring(0, 20)}...\n\nIn a real app, you would send this token to your server to send push notifications.`
);
};
return (
<View style={styles.container}>
<Text style={styles.title}>Push Notifications</Text>
<View style={styles.statusContainer}>
<Text style={styles.statusTitle}>Status</Text>
<Text style={styles.statusText}>
Permission: {permission ? '✅ Granted' : '❌ Denied'}
</Text>
<Text style={styles.statusText}>
Token: {token ? '✅ Available' : '❌ Not Available'}
</Text>
{token && (
<Text style={styles.tokenText}>
{token.substring(0, 30)}...
</Text>
)}
</View>
<View style={styles.buttonContainer}>
<TouchableOpacity style={styles.button} onPress={requestPermission}>
<Text style={styles.buttonText}>🔐 Request Permission</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button} onPress={scheduleLocalNotification}>
<Text style={styles.buttonText}>🔔 Send Local Notification</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button} onPress={scheduleDelayedNotification}>
<Text style={styles.buttonText}>⏰ Schedule Delayed Notification</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.button} onPress={sendTestNotification}>
<Text style={styles.buttonText}>📤 Send Test Notification</Text>
</TouchableOpacity>
<TouchableOpacity style={[styles.button, styles.clearButton]} onPress={cancelAllNotifications}>
<Text style={styles.buttonText}>🗑️ Cancel All Notifications</Text>
</TouchableOpacity>
</View>
<View style={styles.infoContainer}>
<Text style={styles.infoTitle}>Note:</Text>
<Text style={styles.infoText}>
• Local notifications work immediately{'
'}
• Remote notifications require server setup{'
'}
• Test on physical device for best results{'
'}
• Check notification settings in device settings
</Text>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
backgroundColor: '#f5f5f5',
},
title: {
fontSize: 24,
fontWeight: 'bold',
textAlign: 'center',
marginBottom: 30,
color: '#333',
},
statusContainer: {
backgroundColor: 'white',
padding: 20,
borderRadius: 8,
marginBottom: 30,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
},
statusTitle: {
fontSize: 18,
fontWeight: 'bold',
color: '#333',
marginBottom: 15,
textAlign: 'center',
},
statusText: {
fontSize: 14,
color: '#666',
marginBottom: 8,
},
tokenText: {
fontSize: 12,
color: '#999',
fontFamily: Platform.OS === 'ios' ? 'Courier' : 'monospace',
marginTop: 10,
},
buttonContainer: {
gap: 15,
},
button: {
backgroundColor: '#2196F3',
padding: 15,
borderRadius: 8,
alignItems: 'center',
},
clearButton: {
backgroundColor: '#f44336',
},
buttonText: {
color: 'white',
fontSize: 16,
fontWeight: 'bold',
},
infoContainer: {
backgroundColor: '#e3f2fd',
padding: 15,
borderRadius: 8,
marginTop: 20,
},
infoTitle: {
fontSize: 16,
fontWeight: 'bold',
color: '#1976d2',
marginBottom: 8,
},
infoText: {
fontSize: 14,
color: '#1976d2',
lineHeight: 20,
},
});
export default PushNotifications;