import React, { useState, useEffect, useRef } from 'react'; import { Alert, Platform } from 'react-native'; import * as Device from 'expo-device'; import * as Notifications from 'expo-notifications'; import Constants from 'expo-constants'; import { NotificationMessage } from '@/constants/Types'; Notifications.setNotificationHandler({ handleNotification: async () => ({ shouldShowAlert: true, shouldPlaySound: false, shouldSetBadge: false, }), }); export const sendPushNotification = async(expoPushToken: string | null, notification: NotificationMessage) => { if (!expoPushToken) { Alert.alert('Error', 'No push token found.'); return; } const message = { to: expoPushToken, sound: notification.sound ?? 'default', title: notification.title, body: notification.body, data: notification.data ?? {}, }; try { const response = await fetch('https://exp.host/--/api/v2/push/send', { method: 'POST', headers: { Accept: 'application/json', 'Accept-encoding': 'gzip, deflate', 'Content-Type': 'application/json', }, body: JSON.stringify(message), }); const result = await response.json(); } catch (error) { console.error('Error sending push notification:', error); Alert.alert('Error', 'Failed to send push notification.'); } }; const handleRegistrationError = (errorMessage: string) => { alert(errorMessage); throw new Error(errorMessage); }; async function registerForPushNotificationsAsync() { let token; if (Platform.OS === 'android') { await Notifications.setNotificationChannelAsync('default', { name: 'default', importance: Notifications.AndroidImportance.MAX, vibrationPattern: [0, 250, 250, 250], lightColor: '#FF231F7C', }); } if (Device.isDevice) { 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; } const projectId = Constants.expoConfig?.extra?.eas?.projectId; if (!projectId) { alert('Project ID not found'); return; } token = (await Notifications.getExpoPushTokenAsync({ projectId })).data; } else { alert('Must use physical device for Push Notifications'); } return token; } export function PushNotificationManager({ children }: { children: React.ReactNode }) { const [expoPushToken, setExpoPushToken] = useState(''); const [notification, setNotification] = useState(undefined); const notificationListener = useRef(); const responseListener = useRef(); useEffect(() => { registerForPushNotificationsAsync().then(token => setExpoPushToken(token)); notificationListener.current = Notifications.addNotificationReceivedListener(notification => { setNotification(notification); }); responseListener.current = Notifications.addNotificationResponseReceivedListener(response => { console.log(response); // Handle notification response here }); return () => { Notifications.removeNotificationSubscription(notificationListener.current!); Notifications.removeNotificationSubscription(responseListener.current!); }; }, []); return <>{children}; }