Skip to content

Commit dbf3084

Browse files
committed
feat: 알림 허용 버튼
1 parent 8f926a5 commit dbf3084

3 files changed

Lines changed: 86 additions & 23 deletions

File tree

fe/src/app/page.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,21 @@
33
import { useEffect } from "react";
44
import { useFirebase } from '@/hooks/useFirebase';
55
import { MatchList } from '@/components/modules/MatchList';
6+
import { NotificationPrompt } from '@/components/modules/NotificationPrompt';
67

78
export default function Home() {
8-
const { notificationPermission } = useFirebase();
9+
const { notificationPermission, requestNotificationPermission } = useFirebase();
910

1011
useEffect(() => {
11-
// 알림 권한 상태 로깅 (디버깅용)
1212
console.log('Notification Permission:', notificationPermission);
1313
}, [notificationPermission]);
1414

1515
return (
1616
<main className="flex min-h-screen flex-col items-center p-4 md:p-24">
17+
<NotificationPrompt
18+
permission={notificationPermission}
19+
onRequestPermission={requestNotificationPermission}
20+
/>
1721
<MatchList />
1822
</main>
1923
);
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
interface Props {
2+
permission: NotificationPermission;
3+
onRequestPermission: () => Promise<void>;
4+
}
5+
6+
export const NotificationPrompt = ({
7+
permission,
8+
onRequestPermission,
9+
}: Props) => {
10+
switch (permission) {
11+
case 'default':
12+
return (
13+
<div className="mb-4 p-4 bg-blue-100 rounded-lg">
14+
<p className="mb-2">손흥민의 경기 알림을 받아보시겠습니까?</p>
15+
<button
16+
onClick={onRequestPermission}
17+
className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition-colors"
18+
>
19+
알림 받기
20+
</button>
21+
</div>
22+
);
23+
case 'denied':
24+
return (
25+
<div className="mb-4 p-4 bg-yellow-100 rounded-lg">
26+
<p className="text-sm text-yellow-800">
27+
알림이 차단되어 있습니다. 브라우저 설정에서 알림을 허용해주세요.
28+
</p>
29+
</div>
30+
);
31+
default:
32+
return null;
33+
}
34+
};

fe/src/hooks/useFirebase.ts

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import { useEffect, useState } from 'react';
22
import { initializeApp } from 'firebase/app';
3-
import { getMessaging, getToken } from 'firebase/messaging';
3+
import { getMessaging, getToken, Messaging } from 'firebase/messaging';
44
import { firebaseConfig } from '@/constants/config';
55

66
export const useFirebase = () => {
77
const [fcmToken, setFcmToken] = useState<string | null>(null);
88
const [notificationPermission, setNotificationPermission] = useState<NotificationPermission>('default');
9+
const [messaging, setMessaging] = useState<Messaging | null>(null);
910

1011
const registerTokenWithServer = async (token: string) => {
1112
try {
@@ -26,33 +27,56 @@ export const useFirebase = () => {
2627
}
2728
};
2829

30+
const requestNotificationPermission = async () => {
31+
try {
32+
if (!messaging) {
33+
console.error('Firebase Messaging이 초기화되지 않았습니다.');
34+
return;
35+
}
36+
37+
console.log('알림 권한 요청 시작');
38+
const permission = await Notification.requestPermission();
39+
console.log('권한 요청 결과:', permission);
40+
setNotificationPermission(permission);
41+
42+
if (permission === 'granted') {
43+
console.log('권한이 허용됨, 토큰 요청 시작');
44+
const token = await getToken(messaging, {
45+
vapidKey: process.env.NEXT_PUBLIC_FIREBASE_VAPID_KEY
46+
});
47+
48+
if (token) {
49+
console.log('FCM 토큰 발급 성공:', token);
50+
setFcmToken(token);
51+
await registerTokenWithServer(token);
52+
} else {
53+
console.log('토큰을 받지 못했습니다.');
54+
}
55+
} else {
56+
console.log('알림 권한이 거부되었습니다.');
57+
}
58+
} catch (error) {
59+
console.error('알림 권한 요청 에러:', error);
60+
console.error('에러 상세:', error instanceof Error ? error.message : '알 수 없는 에러');
61+
}
62+
};
63+
2964
useEffect(() => {
3065
const initializeFirebase = async () => {
3166
try {
32-
// Firebase 초기화
67+
console.log('Firebase 초기화 시작');
3368
const app = initializeApp(firebaseConfig);
34-
const messaging = getMessaging(app);
35-
36-
// 알림 권한 확인
37-
const permission = await Notification.requestPermission();
38-
console.log('permission', permission);
39-
setNotificationPermission(permission);
69+
const messagingInstance = getMessaging(app);
70+
setMessaging(messagingInstance);
71+
console.log('Firebase 초기화 완료');
4072

41-
if (permission === 'granted') {
42-
// FCM 토큰 얻기
43-
const token = await getToken(messaging, {
44-
vapidKey: process.env.NEXT_PUBLIC_FIREBASE_VAPID_KEY
45-
});
46-
47-
if (token) {
48-
console.log('FCM 토큰:', token);
49-
setFcmToken(token);
50-
// 서버에 토큰 등록
51-
await registerTokenWithServer(token);
52-
}
53-
}
73+
// 현재 알림 권한 상태 확인
74+
const currentPermission = Notification.permission;
75+
console.log('현재 알림 권한 상태:', currentPermission);
76+
setNotificationPermission(currentPermission);
5477
} catch (error) {
5578
console.error('Firebase 초기화 에러:', error);
79+
console.error('에러 상세:', error instanceof Error ? error.message : '알 수 없는 에러');
5680
}
5781
};
5882

@@ -62,5 +86,6 @@ export const useFirebase = () => {
6286
return {
6387
fcmToken,
6488
notificationPermission,
89+
requestNotificationPermission,
6590
};
6691
};

0 commit comments

Comments
 (0)