/** * Sample React Native App * https://github.com/facebook/react-native * * @format * @flow */ import React, { Component } from 'react' import { StatusBar, StyleSheet, Text, TouchableOpacity, Platform } from 'react-native' import MainNav from './src/navigation/MainNav' import messaging from "@react-native-firebase/messaging" import notifee from '@notifee/react-native'; import { persistor, store } from './src/redux/store' import { Provider } from 'react-redux' import { registerDevice } from './src/api/UserApi' import { appSetDevice, appSetPushToken } from './src/redux/app/action' import { setLanguage, setToken } from 'src/api/api' import { PersistGate } from 'redux-persist/integration/react' import Toast from 'react-native-toast-message' import SplashScreen from 'react-native-splash-screen' import { setBaseUrlByServerMode } from './src/api/api' import { Settings } from 'react-native-fbsdk-next'; Text.defaultProps = Text.defaultProps || {} Text.defaultProps.allowFontScaling = false if (TouchableOpacity.defaultProps == null) TouchableOpacity.defaultProps = {} TouchableOpacity.defaultProps.activeOpacity = 0.7 // setApiStore(store) class App extends Component { constructor(props) { super(props) this._setDataFromInitState = this._setDataFromInitState.bind(this) } componentDidMount = async () => { SplashScreen.hide() Settings.initializeSDK(); // ไม่ต้องขอ FCM token ที่นี่ เพราะจะทำใน initNotification แล้ว console.log('App initialized'); } // เพิ่ม method ใหม่สำหรับ setup listeners setupNotificationListeners = () => { // Foreground message handler messaging().onMessage(async remoteMessage => { console.log('Foreground notification:', remoteMessage); // Create a channel (required for Android) const channelId = await notifee.createChannel({ id: 'default', name: 'Default Channel', }); // Display a notification await notifee.displayNotification({ title: remoteMessage.notification?.title || 'New Notification', body: remoteMessage.notification?.body || '', android: { channelId, pressAction: { id: 'default', }, }, ios: { foregroundPresentationOptions: { banner: true, badge: true, sound: true, }, }, }); }); // Background/Quit message handler messaging().setBackgroundMessageHandler(async remoteMessage => { console.log('Background notification:', remoteMessage); }); // Notification opened app handler messaging().onNotificationOpenedApp(remoteMessage => { console.log('Notification opened app:', remoteMessage); }); // Check if app was opened from notification messaging() .getInitialNotification() .then(remoteMessage => { if (remoteMessage) { console.log('App opened from notification:', remoteMessage); } }); } initNotification = async () => { try { console.log('Starting notification initialization...'); // ขอ permission ก่อน await this.setPermission(); // รอให้ APNs token พร้อมสำหรับ iOS if (Platform.OS === 'ios') { console.log('Waiting for APNs token on iOS...'); let apnsToken = null; let retry = 0; const maxRetries = 20; // เพิ่มจำนวน retry while (!apnsToken && retry < maxRetries) { try { apnsToken = await messaging().getAPNSToken(); if (!apnsToken) { console.log(`Waiting for APNs token... (${retry + 1}/${maxRetries})`); await new Promise(resolve => setTimeout(resolve, 2000)); // เพิ่มเวลารอ } } catch (error) { console.log('Error getting APNs token:', error); } retry++; } if (apnsToken) { console.log('APNs Token received:', apnsToken); } else { console.log('Failed to get APNs token after retries, continuing anyway...'); // ลองต่อไปแม้ไม่ได้ APNs token } } // ขอ FCM token หลังจากที่ APNs token พร้อมแล้ว let fcmToken = null; let fcmRetry = 0; const maxFcmRetries = 5; while (!fcmToken && fcmRetry < maxFcmRetries) { try { fcmToken = await messaging().getToken(); if (fcmToken) { console.log('FCM Token received:', fcmToken); break; } } catch (error) { console.log(`FCM token error (${fcmRetry + 1}/${maxFcmRetries}):`, error.message); if (fcmRetry < maxFcmRetries - 1) { await new Promise(resolve => setTimeout(resolve, 3000)); } } fcmRetry++; } if (fcmToken) { store.dispatch(appSetPushToken(fcmToken)) const resultSendDevice = await registerDevice(fcmToken) console.log('register_device result =>', resultSendDevice) if (resultSendDevice.ok && resultSendDevice.data.success) { store.dispatch(appSetDevice(resultSendDevice.data.device)) } } else { console.log('Failed to get FCM token after all retries'); } // เพิ่ม notification listeners this.setupNotificationListeners(); } catch (error) { console.log('initNotification error:', error); } } setPermission = async () => { try { console.log('Setting up permissions...'); // ขอ permission ก่อน const authStatus = await messaging().requestPermission({ alert: true, sound: true, badge: true, }); console.log('Permission status:', authStatus); const enabled = authStatus === messaging.AuthorizationStatus.AUTHORIZED || authStatus === messaging.AuthorizationStatus.PROVISIONAL; if (enabled) { console.log('Notification permission granted, registering device...'); await messaging().registerDeviceForRemoteMessages(); // สำหรับ iOS ให้รอสักครู่หลัง register if (Platform.OS === 'ios') { await new Promise(resolve => setTimeout(resolve, 2000)); } } else { console.log('Notification permission denied'); } } catch (error) { console.log('setPermission error:', error) } } _setDataFromInitState() { const appState = store.getState().app let device = appState.device setBaseUrlByServerMode(appState.server_mode) if (appState.token) { setToken(appState.token) } if (appState.lang) { setLanguage(appState.lang) } if (!device) { this.initNotification() } else { this.setPermission() this.setupNotificationListeners() } console.log('app state', appState, device) } render() { return ( ) } } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', }, welcome: { fontSize: 20, textAlign: 'center', margin: 10, }, instructions: { textAlign: 'center', color: '#333333', marginBottom: 5, }, }) export default App