import React, { useState, useEffect, useRef } from 'react';
import { View, Text, Button, ScrollView, Platform } from 'react-native';
import * as Notifications from 'expo-notifications';
import Constants from 'expo-constants';
Notifications.setNotificationHandler({
handleNotification: async () => ({
shouldShowAlert: true,
shouldPlaySound: false,
shouldSetBadge: false,
}),
});
export default function PushNotificationDemo() {
const [expoPushToken, setExpoPushToken] = useState('');
const [notification, setNotification] = useState(null);
const notificationListener = useRef();
const responseListener = useRef();
useEffect(() => {
// Listener called when a notification is received while app is foreground
notificationListener.current = Notifications.addNotificationReceivedListener(notification => {
setNotification(notification);
});
// Listener called when user interacts with a notification
responseListener.current = Notifications.addNotificationResponseReceivedListener(response => {
// Could handle response here if needed
});
return () => {
Notifications.removeNotificationSubscription(notificationListener.current);
Notifications.removeNotificationSubscription(responseListener.current);
};
}, []);
async function registerForPushNotificationsAsync() {
let token;
if (!Constants.isDevice) {
alert('Must use physical device for Push Notifications');
return;
}
const { status: existingStatus } = await Notifications.getPermissionsAsync();
let finalStatus = existingStatus;
if (existingStatus !== 'granted') {
const { status } = await Notifications.requestPermissionsAsync();
finalStatus = status;
}
if (finalStatus !== 'granted') {
alert('Failed to get push token for push notification!');
return;
}
token = (await Notifications.getExpoPushTokenAsync()).data;
setExpoPushToken(token);
if (Platform.OS === 'android') {
Notifications.setNotificationChannelAsync('default', {
name: 'default',
importance: Notifications.AndroidImportance.MAX,
vibrationPattern: [0, 250, 250, 250],
lightColor: '#FF231F7C',
});
}
}
return (
<ScrollView contentContainerStyle={{ padding: 20 }}>
<Text style={{ fontSize: 20, fontWeight: 'bold', marginBottom: 10 }}>Push Notification Demo</Text>
<Text style={{ marginBottom: 5 }}>Device Token:</Text>
<Text selectable style={{ marginBottom: 20 }}>{expoPushToken || 'No token yet'}</Text>
<Text style={{ marginBottom: 5 }}>Last Notification:</Text>
<Text>Title: {notification ? notification.request.content.title : ''}</Text>
<Text>Body: {notification ? notification.request.content.body : ''}</Text>
<View style={{ marginTop: 30 }}>
<Button title="Request Permission" onPress={registerForPushNotificationsAsync} />
</View>
</ScrollView>
);
}
This app screen uses the expo-notifications package to handle push notifications.
When the user taps the "Request Permission" button, the app asks for permission to send notifications. If granted, it fetches the Expo push token and shows it on screen.
The app also sets up listeners to detect when a notification arrives while the app is open (foreground). It updates the screen to show the notification's title and body.
On Android, it creates a notification channel for proper notification behavior.
This setup helps you test push notifications and see the device token needed to send notifications from a server or Expo push service.