From 05c1cac10f413067d7ced1077fad1be79618722a Mon Sep 17 00:00:00 2001 From: bagasbanuna Date: Tue, 16 Dec 2025 17:47:50 +0800 Subject: [PATCH] Penerapan ke database Fix: - android/app/src/main/AndroidManifest.xml - app/(application)/(user)/home.tsx - components/_ShareComponent/NotificationInitializer.tsx - ios/HIPMIBadungConnect.xcodeproj/project.pbxproj - ios/HIPMIBadungConnect/Info.plist - service/api-notifications.ts ### No Issue --- android/app/src/main/AndroidManifest.xml | 2 +- app/(application)/(user)/home.tsx | 2 +- .../NotificationInitializer.tsx | 106 +++++++++++++++--- .../project.pbxproj | 4 +- ios/HIPMIBadungConnect/Info.plist | 2 + service/api-notifications.ts | 44 ++++++-- 6 files changed, 130 insertions(+), 30 deletions(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 6b0bac0..f7e0d60 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -15,7 +15,7 @@ - + diff --git a/app/(application)/(user)/home.tsx b/app/(application)/(user)/home.tsx index a176a08..3d2b5f3 100644 --- a/app/(application)/(user)/home.tsx +++ b/app/(application)/(user)/home.tsx @@ -145,7 +145,7 @@ export default function Application() { } > - router.push("./test-notifications")}>Test Notif + {/* router.push("./test-notifications")}>Test Notif */} diff --git a/components/_ShareComponent/NotificationInitializer.tsx b/components/_ShareComponent/NotificationInitializer.tsx index 62f0949..5d52875 100644 --- a/components/_ShareComponent/NotificationInitializer.tsx +++ b/components/_ShareComponent/NotificationInitializer.tsx @@ -2,27 +2,96 @@ import { useEffect } from "react"; import messaging from "@react-native-firebase/messaging"; import { useForegroundNotifications } from "@/hooks/use-foreground-notifications"; -import { - useNotificationStore, -} from "@/hooks/use-notification-store"; +import { useNotificationStore } from "@/hooks/use-notification-store"; import type { FirebaseMessagingTypes } from "@react-native-firebase/messaging"; +import { useAuth } from "@/hooks/use-auth"; +import { Platform } from "react-native"; +import * as Device from "expo-device"; +import * as Application from "expo-application"; +import { apiDeviceRegisterToken } from "@/service/api-notifications"; + export default function NotificationInitializer() { - // 1. Ambil token FCM (opsional, hanya untuk log) + // Setup handler notifikasi + const { user } = useAuth(); // dari AuthContext + const { addNotification } = useNotificationStore(); + + // Ambil token FCM (opsional, hanya untuk log) useEffect(() => { - const getFCMToken = async () => { - if (!messaging().isSupported()) return; - const authStatus = await messaging().requestPermission(); - if (authStatus === messaging.AuthorizationStatus.AUTHORIZED) { - const token = await messaging().getToken(); - console.log("✅ FCM Token:", token); + if (!user) { + console.log("User not available, skipping token sync"); + return; + } + + // if (user?.id) { + // syncDeviceToken({ userId: user.id }); + // } + + const registerDeviceToken = async () => { + try { + // 1. Minta izin & ambil FCM token + if (!messaging().isSupported()) return; + const authStatus = await messaging().requestPermission(); + if (authStatus === messaging.AuthorizationStatus.AUTHORIZED) { + const token = await messaging().getToken(); + console.log("✅ FCM Token:", token); + } else { + console.warn("Izin notifikasi ditolak"); + return; + } + const fcmToken = await messaging().getToken(); + if (!fcmToken) { + console.warn("Gagal mendapatkan FCM token"); + return; + } + + // 2. Ambil info device + const platform = Platform.OS; // "ios" | "android" + // ? await Device.getUdid() + // : "unknown"; + const model = Device.modelName || "unknown"; + const appVersion = + (Application.nativeApplicationVersion || "unknown") + + "-" + + (Application.nativeBuildVersion || "unknown"); + const deviceId = + Device.osInternalBuildId || Device.modelName + "-" + Date.now(); + + console.log( + "📱 Device info:", + JSON.stringify( + { + fcmToken, + platform, + deviceId, + model, + appVersion, + }, + null, + 2 + ) + ); + + // 3. Kirim ke backend + await apiDeviceRegisterToken({ + data: { + fcmToken, + platform, + deviceId, + model, + appVersion, + userId: user?.id || "", + }, + }); + + console.log("✅ Device token berhasil didaftarkan ke backend"); + } catch (error) { + console.error("❌ Gagal mendaftarkan device token:", error); } }; - getFCMToken(); - }, []); - // 2. Setup handler notifikasi - const { addNotification } = useNotificationStore(); + registerDeviceToken(); + }, [user?.id]); const handleForegroundNotification = ( message: FirebaseMessagingTypes.RemoteMessage @@ -33,9 +102,10 @@ export default function NotificationInitializer() { const safeData: Record = {}; for (const key in rawData) { - safeData[key] = typeof rawData[key] === "string" - ? rawData[key] - : JSON.stringify(rawData[key]); + safeData[key] = + typeof rawData[key] === "string" + ? rawData[key] + : JSON.stringify(rawData[key]); } console.log("📥 Menambahkan ke store:", { title, body, safeData }); @@ -46,4 +116,4 @@ export default function NotificationInitializer() { useForegroundNotifications(handleForegroundNotification); return null; // komponen ini tidak merender apa-apa -} \ No newline at end of file +} diff --git a/ios/HIPMIBadungConnect.xcodeproj/project.pbxproj b/ios/HIPMIBadungConnect.xcodeproj/project.pbxproj index fb1ba31..09b1789 100644 --- a/ios/HIPMIBadungConnect.xcodeproj/project.pbxproj +++ b/ios/HIPMIBadungConnect.xcodeproj/project.pbxproj @@ -458,7 +458,7 @@ ); OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG"; PRODUCT_BUNDLE_IDENTIFIER = "com.anonymous.hipmi-mobile"; - PRODUCT_NAME = HIPMIBadungConnect; + PRODUCT_NAME = "HIPMIBadungConnect"; SWIFT_OBJC_BRIDGING_HEADER = "HIPMIBadungConnect/HIPMIBadungConnect-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; @@ -490,7 +490,7 @@ ); OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE"; PRODUCT_BUNDLE_IDENTIFIER = "com.anonymous.hipmi-mobile"; - PRODUCT_NAME = HIPMIBadungConnect; + PRODUCT_NAME = "HIPMIBadungConnect"; SWIFT_OBJC_BRIDGING_HEADER = "HIPMIBadungConnect/HIPMIBadungConnect-Bridging-Header.h"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; diff --git a/ios/HIPMIBadungConnect/Info.plist b/ios/HIPMIBadungConnect/Info.plist index bd0a77f..3f06716 100644 --- a/ios/HIPMIBadungConnect/Info.plist +++ b/ios/HIPMIBadungConnect/Info.plist @@ -55,6 +55,8 @@ NSCameraUsageDescription Allow $(PRODUCT_NAME) to access your camera + NSFaceIDUsageDescription + Allow $(PRODUCT_NAME) to access your Face ID biometric data. NSLocationAlwaysAndWhenInUseUsageDescription Allow $(PRODUCT_NAME) to access your location NSLocationAlwaysUsageDescription diff --git a/service/api-notifications.ts b/service/api-notifications.ts index 85ff6a6..a776a71 100644 --- a/service/api-notifications.ts +++ b/service/api-notifications.ts @@ -1,23 +1,51 @@ import { apiConfig } from "./api-config"; - type NotificationProp = { - fcmToken: string - title: string, - body: Object -} + fcmToken: string; + title: string; + body: Object; +}; - -export async function apiNotificationsSend({ data }: { data: NotificationProp }) { +export async function apiNotificationsSend({ + data, +}: { + data: NotificationProp; +}) { try { const response = await apiConfig.post(`/mobile/notifications`, { data: data, }); - console.log("Fecth Notif", response.data) + console.log("Fecth Notif", response.data); return response.data; } catch (error) { throw error; } } + +type DeviceTokenData = { + fcmToken: string; + platform: string; + deviceId: string; + model: string; + appVersion: string; + userId: string; +}; + +export async function apiDeviceRegisterToken({ + data, +}: { + data: DeviceTokenData; +}) { + try { + const response = await apiConfig.post(`/mobile/auth/device-tokens`, { + data: data, + }); + console.log("Device token registered:", response.data); + return response.data; + } catch (error) { + console.error("Failed to register device token:", error); + throw error; + } +} -- 2.49.1