From 7e8ddbb1bea7ba6057e11e985b1117f6b07c0865 Mon Sep 17 00:00:00 2001 From: kanyanat Date: Wed, 3 Dec 2025 18:12:54 +0700 Subject: [PATCH] fix push notification with @notifee/react-native lib --- ios/csareactrn60/AppDelegate.mm | 26 +++++++++++++---- src/screens/login/Login.js | 51 +++++++++++---------------------- 2 files changed, 37 insertions(+), 40 deletions(-) diff --git a/ios/csareactrn60/AppDelegate.mm b/ios/csareactrn60/AppDelegate.mm index fcd0910..13c9dec 100644 --- a/ios/csareactrn60/AppDelegate.mm +++ b/ios/csareactrn60/AppDelegate.mm @@ -12,6 +12,7 @@ #import #import "RNSplashScreen.h" +#import #import @@ -27,6 +28,11 @@ [FIRApp configure]; } + // ตั้งค่า Notifee delegate ก่อน + [RNNotifee onBackgroundEvent:^(NSDictionary * _Nonnull event) { + // Handle background events + }]; + // เพิ่ม notification center delegate UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; center.delegate = self; @@ -81,23 +87,31 @@ willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler { - // ถ้าเป็น Remote Notification (จาก FCM) ให้ซ่อนไว้ (None) เพื่อไม่ให้ซ้ำกับที่ Notifee จะแสดง - if ([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) { - completionHandler(UNNotificationPresentationOptionNone); - } else { - // ถ้าเป็น Local Notification (จาก Notifee) ให้แสดงผล (Alert/Sound/Badge) - completionHandler(UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionSound); + // ให้ Notifee จัดการ notification ก่อน + if ([RNNotifee willPresentNotification:notification withCompletionHandler:completionHandler]) { + return; } + + // ถ้า Notifee ไม่จัดการ ให้แสดงแบบปกติ + completionHandler(UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionSound); } - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler { + + // ให้ Notifee จัดการ response ก่อน + if ([RNNotifee didReceiveNotificationResponse:response withCompletionHandler:completionHandler]) { + return; + } + completionHandler(); } - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { + // ส่ง token ให้ทั้ง Firebase และ Notifee [FIRMessaging messaging].APNSToken = deviceToken; + [RNNotifee didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; } - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { diff --git a/src/screens/login/Login.js b/src/screens/login/Login.js index d175031..d1bb94f 100644 --- a/src/screens/login/Login.js +++ b/src/screens/login/Login.js @@ -16,6 +16,7 @@ import IndicatorLoading from '../../components/IndicatorLoading'; import { locale, t } from '../../utils/i18n' import moment from "moment"; import messaging from "@react-native-firebase/messaging"; +import NotificationService from '../../utils/NotificationService'; class LoginScreen extends Component { @@ -36,7 +37,11 @@ class LoginScreen extends Component { async componentDidMount() { await messaging().deleteToken() console.log('deletetoken'); - + + // Initialize notification service + await NotificationService.initialize(); + await NotificationService.createNotificationChannel(); + await NotificationService.setupBackgroundHandler(); } async _login() { @@ -50,45 +55,24 @@ class LoginScreen extends Component { if (regex.test(this.state.username) === true) { console.log('true') try { - const authStatus = await messaging().requestPermission({ - alert: true, - sound: true, - badge: true, - }); - - console.log('authStatus >>> ', authStatus) - const enabled = - authStatus === messaging.AuthorizationStatus.AUTHORIZED || - authStatus === messaging.AuthorizationStatus.PROVISIONAL; - - if (enabled) { - console.log('Notification permission granted.'); - await messaging().registerDeviceForRemoteMessages(); - - if (Platform.OS === 'ios') { - let apnsToken = await messaging().getAPNSToken(); - let retry = 0; - while (!apnsToken && retry < 10) { - console.log('Waiting for APNs token...'); - await new Promise(resolve => setTimeout(resolve, 1000)); - apnsToken = await messaging().getAPNSToken(); - retry++; - } - console.log('APNs Token:', apnsToken); + // ใช้ NotificationService + const isPermissionGranted = await NotificationService.initialize(); + + if (isPermissionGranted) { + const tokens = await NotificationService.getTokens(); + fcmToken = tokens.fcmToken; + + console.log('FCM Token:', fcmToken); + if (tokens.apnsToken) { + console.log('APNs Token:', tokens.apnsToken); } - - fcmToken = await messaging().getToken(); - console.log('fcmToken >>>> ', fcmToken) } else { console.log('Notification permission denied.'); } } catch (error) { - console.error('Failed to request notification permission:', error); + console.error('Failed to get notification tokens:', error); } - // const fcmToken = await messaging().getAPNSToken() - console.log('await messaging().getAPNSToken() <<<<<< ', fcmToken) - let params = { // mobile: this.state.username, @@ -98,7 +82,6 @@ class LoginScreen extends Component { } console.log('params >> ', params) - // console.log('fcmToken >>>>>>>>>>>>>>>>>>>>>>>>> ', fcmToken) this.setState({ isLoading: true }) login(params) .then((res) => {