Untitled
unknown
plain_text
16 days ago
7.3 kB
4
Indexable
import { useEffect, useRef, useState } from 'react'; import * as Notifications from 'expo-notifications'; import { EventSubscription } from 'expo-modules-core'; import notificationService from '../services/notificationService'; import firebaseMessagingService from '../services/firebaseMessagingService'; import { Platform } from 'react-native'; import messaging from '@react-native-firebase/messaging'; export const useNotifications = () => { const notificationListener = useRef<EventSubscription>(); const responseListener = useRef<EventSubscription>(); const firebaseMessageListener = useRef<() => void>(); const firebaseNotificationOpenListener = useRef<() => void>(); const [fcmToken, setFcmToken] = useState<string | null>(null); useEffect(() => { const setupNotifications = async () => { try { console.log('Setting up notifications...'); // Try Firebase first try { console.log('Setting up Firebase messaging...'); // Request permission for Firebase notifications const hasPermission = await firebaseMessagingService.requestPermission(); if (hasPermission) { console.log('Firebase permission granted, getting FCM token...'); // For iOS, we need to make sure we're registered for remote notifications if (Platform.OS === 'ios') { try { // Force register for remote messages await messaging().registerDeviceForRemoteMessages(); console.log('Successfully registered for remote messages'); } catch (registerError) { console.error('Error registering for remote messages:', registerError); } } // Get the FCM token const token = await firebaseMessagingService.getFCMToken(); if (token) { setFcmToken(token); console.log('Firebase Messaging Token:', token); // Set up Android notification channel if (Platform.OS === 'android') { await firebaseMessagingService.createAndroidChannel(); } } else { console.error('Failed to get FCM token even though permission was granted'); } } else { console.warn('Firebase messaging permission not granted'); } } catch (firebaseError) { console.error('Error setting up Firebase messaging:', firebaseError); } // Register for Expo push notifications as a fallback console.log('Setting up Expo notifications...'); const expoPushToken = await notificationService.registerForPushNotifications(); console.log('Expo Push Token:', expoPushToken); // Add Expo notification listeners notificationListener.current = notificationService.addNotificationReceivedListener( notification => { console.log('Expo notification received in listener:', notification); // You can show a local notification here if needed } ); responseListener.current = notificationService.addNotificationResponseReceivedListener( response => { console.log('Expo notification response in listener:', response); // Handle notification response (e.g., navigate to a screen) } ); // Add Firebase notification listeners firebaseMessageListener.current = firebaseMessagingService.onForegroundMessage( remoteMessage => { console.log('Firebase foreground message received in listener:', remoteMessage); // Show a local notification for Firebase messages received in foreground if (remoteMessage.notification) { notificationService.scheduleLocalNotification( remoteMessage.notification.title || 'New Message', remoteMessage.notification.body || 'You have a new notification', 0 ); } } ); firebaseNotificationOpenListener.current = firebaseMessagingService.onNotificationOpen( remoteMessage => { console.log('Firebase notification opened in listener:', remoteMessage); // Handle notification open (e.g., navigate to a screen) } ); // Check if app was opened from a Firebase notification const initialNotification = await firebaseMessagingService.getInitialNotification(); if (initialNotification) { console.log('App opened from Firebase notification:', initialNotification); // Handle initial notification (e.g., navigate to a screen) } } catch (error) { console.error('Error setting up notifications:', error); } }; setupNotifications(); // Cleanup listeners on unmount return () => { if (notificationListener.current) { notificationListener.current.remove(); } if (responseListener.current) { responseListener.current.remove(); } if (firebaseMessageListener.current) { firebaseMessageListener.current(); } if (firebaseNotificationOpenListener.current) { firebaseNotificationOpenListener.current(); } }; }, []); const sendTestNotification = async () => { await notificationService.scheduleLocalNotification( 'Test Notification', 'This is a test notification!', 2 // Show after 2 seconds ); }; const sendRemoteTestNotification = async ( token: string, title: string, body: string, data: Record<string, any> = {} ) => { await notificationService.sendRemotePushNotification(token, title, body, data); }; const subscribeToTopic = async (topic: string) => { await firebaseMessagingService.subscribeToTopic(topic); }; const unsubscribeFromTopic = async (topic: string) => { await firebaseMessagingService.unsubscribeFromTopic(topic); }; // Get the best available token for push notifications const getBestAvailableToken = (): string | undefined => { // Prefer FCM token if available if (fcmToken) { return fcmToken; } // Fall back to Expo Push Token return notificationService.expoPushToken; }; // Function to manually retry getting the FCM token const retryGetFCMToken = async (): Promise<void> => { try { console.log('Manually retrying to get FCM token...'); const token = await firebaseMessagingService.getFCMToken(); if (token) { setFcmToken(token); console.log('Successfully got FCM token on retry:', token); } else { console.error('Failed to get FCM token on retry'); } } catch (error) { console.error('Error retrying to get FCM token:', error); } }; return { expoPushToken: notificationService.expoPushToken, fcmToken, // Provide a best available token that will use FCM if available, otherwise Expo bestAvailableToken: getBestAvailableToken(), sendTestNotification, sendRemoteTestNotification, subscribeToTopic, unsubscribeFromTopic, retryGetFCMToken, // Add the retry function }; };
Editor is loading...
Leave a Comment