diff --git a/Time-Up/App.tsx b/Time-Up/App.tsx index 8d0cbaa..f4a896c 100644 --- a/Time-Up/App.tsx +++ b/Time-Up/App.tsx @@ -44,7 +44,8 @@ import SetScheduleRepeatPage from './src/pages/SetScheduleRepeatPage'; import ViewScheduleDetailPage from './src/pages/ViewScheduleDetailPage'; import { getAccessToken } from './src/utils/storage'; -import { requestWebPushToken } from './src/utils/webPush'; +import { initWebPush } from './src/utils/webPush'; +import { requestWebPushToken } from './src/utils/webToken'; const queryClient = new QueryClient(); @@ -144,6 +145,18 @@ export default function App() { }; }, []); + useEffect(() => { + (async () => { + try { + const token = await initWebPush(); + console.log('FCM 웹 토큰:', token); + // 이미 토큰 저장 API는 구현했다 했으니 여기선 로깅만 + } catch (e) { + console.warn('웹 푸시 초기화 실패:', e); + } + })(); + }, []); + if (!mapsLoaded || !initialRoute) return null; const content = ( diff --git a/Time-Up/src/pages/Alarm/My/EditMyAlarmPage.tsx b/Time-Up/src/pages/Alarm/My/EditMyAlarmPage.tsx index ff6e019..23a86f7 100644 --- a/Time-Up/src/pages/Alarm/My/EditMyAlarmPage.tsx +++ b/Time-Up/src/pages/Alarm/My/EditMyAlarmPage.tsx @@ -466,7 +466,7 @@ export default function EditMyAlarmPage() { - + diff --git a/Time-Up/src/pages/Alarm/My/MyAlarmDetailPage.tsx b/Time-Up/src/pages/Alarm/My/MyAlarmDetailPage.tsx index 8f5290e..c8b8bfa 100644 --- a/Time-Up/src/pages/Alarm/My/MyAlarmDetailPage.tsx +++ b/Time-Up/src/pages/Alarm/My/MyAlarmDetailPage.tsx @@ -172,7 +172,7 @@ export default function MyAlarmDetailPage() { - + diff --git a/Time-Up/src/pages/Alarm/My/MyAlarmPage.tsx b/Time-Up/src/pages/Alarm/My/MyAlarmPage.tsx index 75a9cb9..98aa8b3 100644 --- a/Time-Up/src/pages/Alarm/My/MyAlarmPage.tsx +++ b/Time-Up/src/pages/Alarm/My/MyAlarmPage.tsx @@ -92,7 +92,6 @@ export default function MyAlarmPage() { } }; - // const handleToggleAutoAlarm = async () => { // try { // if (nextAutoAlarm?.auto_alarm_id != null) { diff --git a/Time-Up/src/pages/Alarm/WakeUp/EditWakeUpAlarmPage.tsx b/Time-Up/src/pages/Alarm/WakeUp/EditWakeUpAlarmPage.tsx index 4e81252..090efae 100644 --- a/Time-Up/src/pages/Alarm/WakeUp/EditWakeUpAlarmPage.tsx +++ b/Time-Up/src/pages/Alarm/WakeUp/EditWakeUpAlarmPage.tsx @@ -6,7 +6,7 @@ import { AlarmItem } from '@/src/types/alarm'; import { toPutWakeupAlarmRequest } from '@/src/utils/alarmTransform'; import { BottomSheetModal, BottomSheetView } from '@gorhom/bottom-sheet'; import React, { useCallback, useMemo, useRef, useState } from 'react'; -import { Dimensions, Platform, ScrollView, Text, TextInput, TouchableOpacity, View } from 'react-native'; +import { Dimensions, Platform, Text, TextInput, TouchableOpacity, View } from 'react-native'; import { GestureHandlerRootView } from 'react-native-gesture-handler'; import ToggleSwitch from '../../../components/common/ToggleSwitch'; import { Day, useAlarmContext } from '../../../contexts/AlarmContext'; @@ -159,7 +159,6 @@ export default function EditWakeUpAlarmPage() { return ( - - + 반복요일 @@ -356,12 +355,12 @@ export default function EditWakeUpAlarmPage() { - + ); diff --git a/Time-Up/src/pages/Alarm/WakeUp/WakeUpAlarmDetailPage.tsx b/Time-Up/src/pages/Alarm/WakeUp/WakeUpAlarmDetailPage.tsx index 622cd27..fb1266f 100644 --- a/Time-Up/src/pages/Alarm/WakeUp/WakeUpAlarmDetailPage.tsx +++ b/Time-Up/src/pages/Alarm/WakeUp/WakeUpAlarmDetailPage.tsx @@ -182,7 +182,7 @@ export default function WakeUpAlarmDetailPage() { - + diff --git a/Time-Up/src/pages/Onboarding/OnboardingPage.tsx b/Time-Up/src/pages/Onboarding/OnboardingPage.tsx index 61789f6..d20ed83 100644 --- a/Time-Up/src/pages/Onboarding/OnboardingPage.tsx +++ b/Time-Up/src/pages/Onboarding/OnboardingPage.tsx @@ -67,7 +67,6 @@ export default function OnboardingPage() { } if (data.success?.isNew) { - debugger; try { await refreshAlarms(); } catch (e) { diff --git a/Time-Up/src/utils/webPush.ts b/Time-Up/src/utils/webPush.ts index f3a7ce0..a7cdb4c 100644 --- a/Time-Up/src/utils/webPush.ts +++ b/Time-Up/src/utils/webPush.ts @@ -1,6 +1,7 @@ // src/utils/webPush.ts +// webPush.ts (예: 앱 시작 시 1회 호출) import { initializeApp } from 'firebase/app'; -import { getMessaging, getToken } from 'firebase/messaging'; +import { getMessaging, getToken, isSupported, onMessage } from 'firebase/messaging'; const firebaseConfig = { apiKey: "AIzaSyAEAKbupll7pRrAuhCtI0SbHRAx-rXj7oM", @@ -11,59 +12,31 @@ const firebaseConfig = { }; const app = initializeApp(firebaseConfig); -export const messaging = getMessaging(app); -// 1) 푸시 권한 요청 + 2) 서비스워커 등록 + 3) FCM 웹 토큰 발급 -// export async function requestWebPushToken(): Promise { -// if (!('Notification' in window)) return null; - -// const permission = await Notification.requestPermission(); -// if (permission !== 'granted') return null; - -// // 이미 public/index.html에서 /firebase-messaging-sw.js 를 등록했지만, -// // 안전하게 등록 객체를 getToken에 넘겨 위치를 명시. (Firebase 공식 지원) -// const registration = await navigator.serviceWorker.getRegistration('/') -// ?? await navigator.serviceWorker.register('/firebase-messaging-sw.js'); - -// const token = await getToken(messaging, { -// vapidKey: 'BK6LHOnQzm8od0iib8gPwgv7K6eI43xNDDhpVRLkNTXWZ4jVfxCfaTwy-HPNqHeoiPyM3C3o7sUhPIOHBSetyUc', -// serviceWorkerRegistration: registration, -// }); - -// return token || null; -// } +export async function initWebPush() { + const supported = await isSupported(); + if (!supported) { + console.warn('이 브라우저는 FCM을 지원하지 않습니다.'); + return null; + } -export async function requestWebPushToken(): Promise { - if (!('Notification' in window)) return null; + const registration = await navigator.serviceWorker.register('/firebase-messaging-sw.js', { scope: '/' }); - const permission = await Notification.requestPermission(); - if (permission !== 'granted') { - console.warn('웹 푸시 권한 거부됨'); + const perm = await Notification.requestPermission(); + if (perm !== 'granted') { + console.warn('알림 권한이 거부되었습니다.'); return null; } - let registration = await navigator.serviceWorker.getRegistration('/'); - if (!registration) { - registration = await navigator.serviceWorker.register('/firebase-messaging-sw.js', { scope: '/' }); - } + const messaging = getMessaging(app); + const token = await getToken(messaging, { + vapidKey: 'BK6LHOnQzm8od0iib8gPwgv7K6eI43xNDDhpVRLkNTXWZ4jVfxCfaTwy-HPNqHeoiPyM3C3o7sUhPIOHBSetyUc', + serviceWorkerRegistration: registration, + }); - // 2) 활성화(ready)까지 대기 - await navigator.serviceWorker.ready; + onMessage(messaging, (payload) => { + console.log('[foreground] FCM payload:', payload); + }); - try { - const token = await getToken(messaging, { - vapidKey: 'BK6LHOnQzm8od0iib8gPwgv7K6eI43xNDDhpVRLkNTXWZ4jVfxCfaTwy-HPNqHeoiPyM3C3o7sUhPIOHBSetyUc', - serviceWorkerRegistration: registration, - }); - if (!token) { - console.warn('토큰이 비어 있음 (권한/HTTPS/도메인/스코프 확인 필요)'); - return null; - } - console.log('Web FCM Token:', token); // 정상 발급 - return token; - } catch (e: any) { - console.error('getToken 실패:', e?.code, e?.message, e); - return null; - } + return token; } - diff --git a/Time-Up/src/utils/webToken.ts b/Time-Up/src/utils/webToken.ts new file mode 100644 index 0000000..6bf9cd9 --- /dev/null +++ b/Time-Up/src/utils/webToken.ts @@ -0,0 +1,69 @@ +// src/utils/webToken.ts +import { initializeApp } from 'firebase/app'; +import { getMessaging, getToken } from 'firebase/messaging'; + +const firebaseConfig = { + apiKey: "AIzaSyAEAKbupll7pRrAuhCtI0SbHRAx-rXj7oM", + authDomain: "timeup-80358.firebaseapp.com", + projectId: "timeup-80358", + messagingSenderId: "482152461783", + appId: "1:482152461783:web:8ee854bcf8cad1ab3bc792", +}; + +const app = initializeApp(firebaseConfig); +export const messaging = getMessaging(app); + +// 1) 푸시 권한 요청 + 2) 서비스워커 등록 + 3) FCM 웹 토큰 발급 +// export async function requestWebPushToken(): Promise { +// if (!('Notification' in window)) return null; + +// const permission = await Notification.requestPermission(); +// if (permission !== 'granted') return null; + +// // 이미 public/index.html에서 /firebase-messaging-sw.js 를 등록했지만, +// // 안전하게 등록 객체를 getToken에 넘겨 위치를 명시. (Firebase 공식 지원) +// const registration = await navigator.serviceWorker.getRegistration('/') +// ?? await navigator.serviceWorker.register('/firebase-messaging-sw.js'); + +// const token = await getToken(messaging, { +// vapidKey: 'BK6LHOnQzm8od0iib8gPwgv7K6eI43xNDDhpVRLkNTXWZ4jVfxCfaTwy-HPNqHeoiPyM3C3o7sUhPIOHBSetyUc', +// serviceWorkerRegistration: registration, +// }); + +// return token || null; +// } + +export async function requestWebPushToken(): Promise { + if (!('Notification' in window)) return null; + + const permission = await Notification.requestPermission(); + if (permission !== 'granted') { + console.warn('웹 푸시 권한 거부됨'); + return null; + } + + let registration = await navigator.serviceWorker.getRegistration('/'); + if (!registration) { + registration = await navigator.serviceWorker.register('/firebase-messaging-sw.js', { scope: '/' }); + } + + // 2) 활성화(ready)까지 대기 + await navigator.serviceWorker.ready; + + try { + const token = await getToken(messaging, { + vapidKey: 'BK6LHOnQzm8od0iib8gPwgv7K6eI43xNDDhpVRLkNTXWZ4jVfxCfaTwy-HPNqHeoiPyM3C3o7sUhPIOHBSetyUc', + serviceWorkerRegistration: registration, + }); + if (!token) { + console.warn('토큰이 비어 있음 (권한/HTTPS/도메인/스코프 확인 필요)'); + return null; + } + console.log('Web FCM Token:', token); // 정상 발급 + return token; + } catch (e: any) { + console.error('getToken 실패:', e?.code, e?.message, e); + return null; + } +} +