Feat: Firebase FCM 구현 완료, 테스트 중

This commit is contained in:
홍창기 2024-09-26 21:15:23 +09:00
parent 628503dd27
commit de723381b3
7 changed files with 183 additions and 99 deletions

View File

@ -15,6 +15,10 @@
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>
<script
type="module"
src="/serviceWorkerRegistration.js"
></script>
<script <script
type="module" type="module"
src="/src/main.tsx" src="/src/main.tsx"

View File

@ -1,15 +1,41 @@
// import { initializeApp } from 'firebase/app'; /* eslint-disable @typescript-eslint/no-unused-vars */
// import { getMessaging } from 'firebase/messaging'; /* eslint-disable no-undef */
importScripts('https://www.gstatic.com/firebasejs/8.7.1/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/8.7.1/firebase-messaging.js');
// const firebaseConfig = { self.addEventListener('install', (_) => {
// apiKey: import.meta.env.VITE_FIREBASE_API_KEY, self.skipWaiting();
// authDomain: import.meta.env.VITE_FIREBASE_AUTH_DOMAIN, });
// projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID,
// storageBucket: import.meta.env.VITE_FIREBASE_STORAGE_BUCKET,
// messagingSenderId: import.meta.env.VITE_FIREBASE_MESSAGING_SENDER_ID,
// appId: import.meta.env.VITE_FIREBASE_APP_ID,
// measurementId: import.meta.env.VITE_FIREBASE_MEASUREMENT_ID,
// };
// export const app = initializeApp(firebaseConfig); self.addEventListener('activate', (_) => {
// export const messaging = getMessaging(app); console.log('FCM service worker가 실행되었습니다.');
});
const firebaseConfig = {};
firebase.initializeApp(firebaseConfig);
const messaging = firebase.messaging();
messaging.onBackgroundMessage((payload) => {
const notificationTitle = payload.data.title;
const notificationOptions = {
body: payload.data.body,
icon: payload.data.image,
data: {
url: payload.data.url, // 알림 클릭시 이동할 URL
},
};
self.registration.showNotification(notificationTitle, notificationOptions);
});
// 알림 클릭 이벤트 처리
self.addEventListener('notificationclick', (event) => {
event.notification.close(); // 알림 닫기
// 알림에서 설정한 URL로 이동
const clickActionUrl = event.notification.data.url;
if (clickActionUrl) {
event.waitUntil(clients.openWindow(clickActionUrl));
}
});

View File

@ -0,0 +1,56 @@
import { initializeApp } from 'https://www.gstatic.com/firebasejs/9.1.3/firebase-app.js';
import { getMessaging, getToken } from 'https://www.gstatic.com/firebasejs/9.1.3/firebase-messaging.js';
const firebaseConfig = {};
const firebaseApp = initializeApp(firebaseConfig);
const messaging = getMessaging(firebaseApp);
const registerServiceWorker = async () => {
if ('serviceWorker' in navigator) {
try {
console.log('Service Worker 등록 중...');
const firebaseRegistration = await navigator.serviceWorker.register('/firebase-messaging-sw.js');
console.log('Service Worker 등록 성공');
console.log('Service Worker 활성화 중...');
const serviceWorker = await navigator.serviceWorker.ready;
console.log('Service Worker 활성화 성공');
if (serviceWorker && !sessionStorage.getItem('fcmToken')) {
const permission = await Notification.requestPermission();
if (permission === 'granted') {
console.log('알림 권한이 허용되었습니다.');
try {
console.log('FCM 토큰 발급 중...');
const currentToken = await getToken(messaging, {
vapidKey: 'BApIruZrx83suCd09dnDCkFSP_Ts08q38trrIL6GHpChtbjQHTHk_38_JRyTiKLqciHxLQ8iXtie3lvgyb4Iphg',
serviceWorkerRegistration: firebaseRegistration,
});
console.log('FCM 토큰 발급 성공');
if (currentToken) {
sessionStorage.setItem('fcmToken', currentToken);
}
} catch (error) {
console.warn('FCM 토큰을 가져올 수 없습니다.');
}
return;
}
console.log('알림 권한이 거부되었습니다.');
}
} catch (error) {
console.error('Service Worker 등록에 실패했습니다. : ', error);
}
return;
}
console.warn('현재 브라우저에서 Service Worker를 지원하지 않습니다.');
};
registerServiceWorker();

View File

@ -17,6 +17,6 @@ export async function saveFcmToken(token: string) {
return api.post('/auth/fcm', { token }).then(({ data }) => data); return api.post('/auth/fcm', { token }).then(({ data }) => data);
} }
export async function createTestNotification() { export async function createFcmNotification() {
return api.post('/auth/test').then(({ data }) => data); return api.post('/auth/test').then(({ data }) => data);
} }

View File

@ -0,0 +1,60 @@
import { initializeApp } from 'firebase/app';
import { getMessaging, getToken, onMessage } from 'firebase/messaging';
const firebaseConfig = {
apiKey: import.meta.env.VITE_FIREBASE_API_KEY,
authDomain: import.meta.env.VITE_FIREBASE_AUTH_DOMAIN,
projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID,
storageBucket: import.meta.env.VITE_FIREBASE_STORAGE_BUCKET,
messagingSenderId: import.meta.env.VITE_FIREBASE_MESSAGING_SENDER_ID,
appId: import.meta.env.VITE_FIREBASE_APP_ID,
measurementId: import.meta.env.VITE_FIREBASE_MEASUREMENT_ID,
};
const firebaseApp = initializeApp(firebaseConfig);
const messaging = getMessaging(firebaseApp);
const getFcmToken = async () => {
const existingToken = sessionStorage.getItem('fcmToken');
if (existingToken) {
return existingToken; // 이미 토큰이 있는 경우, 해당 토큰을 반환한다.
}
try {
const permission = await Notification.requestPermission();
if (permission === 'granted') {
const currentToken = await getToken(messaging, {
vapidKey: 'BGVbiPhLWWxijrc2jfn9lTyDs-kcSfSinb2bUmEoDXSc8ljx6sWtur9k82vmjBLND06SSeb10oq-rw7zmzrpoPY',
});
if (currentToken) {
sessionStorage.setItem('fcmToken', currentToken);
return currentToken;
}
console.warn('FCM 토큰을 가져올 수 없습니다.');
return null;
}
console.log('알림 권한이 거부되었습니다.');
return null;
} catch (error) {
console.error('FCM 토큰을 가져오는 중 오류가 발생했습니다 : ', error);
return null;
}
};
const handleForegroundMessages = () => {
onMessage(messaging, (payload) => {
console.log('onMessage');
console.log(payload);
if (!payload.data) return;
console.log(payload.data);
});
};
export { getFcmToken, handleForegroundMessages, messaging };

View File

@ -1,13 +0,0 @@
import { initializeApp } from 'firebase/app';
const firebaseConfig = {
apiKey: import.meta.env.VITE_FIREBASE_API_KEY,
authDomain: import.meta.env.VITE_FIREBASE_AUTH_DOMAIN,
projectId: import.meta.env.VITE_FIREBASE_PROJECT_ID,
storageBucket: import.meta.env.VITE_FIREBASE_STORAGE_BUCKET,
messagingSenderId: import.meta.env.VITE_FIREBASE_MESSAGING_SENDER_ID,
appId: import.meta.env.VITE_FIREBASE_APP_ID,
measurementId: import.meta.env.VITE_FIREBASE_MEASUREMENT_ID,
};
export const firebaseApp = initializeApp(firebaseConfig);

View File

@ -1,98 +1,49 @@
import { createTestNotification, saveFcmToken } from '@/api/authApi'; import { createFcmNotification, saveFcmToken } from '@/api/authApi';
import { getFcmToken, handleForegroundMessages } from '@/api/firebaseConfig';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { firebaseApp } from '@/firebase';
import { getMessaging, getToken, onMessage } from 'firebase/messaging';
import { useEffect } from 'react';
export default function FirebaseTest() { export default function FirebaseTest() {
useEffect(() => { const handleSaveFcmToken = async () => {
const messaging = getMessaging(firebaseApp); const fcmToken = await getFcmToken();
onMessage(messaging, (payload) => {
console.log('Message recieved. ', payload);
if (!payload || !payload.notification) return;
const { title, body } = payload.notification;
if (!title || !body) return;
new Notification(title, { body });
});
}, []);
const getFcmToken = async () => {
const existingToken = sessionStorage.getItem('fcmToken');
if (existingToken) {
console.log(existingToken);
return existingToken;
}
try {
const permission = await Notification.requestPermission();
if (permission === 'granted') {
const messaging = getMessaging(firebaseApp);
const currentToken = await getToken(messaging, {
vapidKey: 'BApIruZrx83suCd09dnDCkFSP_Ts08q38trrIL6GHpChtbjQHTHk_38_JRyTiKLqciHxLQ8iXtie3lvgyb4Iphg',
});
if (currentToken) {
console.log(currentToken);
sessionStorage.setItem('fcmToken', currentToken);
return currentToken;
}
console.warn('FCM 토큰을 가져올 수 없습니다. 권한이 없거나 문제가 발생했습니다.');
return null;
}
console.log('알림 권한이 거부되었습니다.');
return null;
} catch (error) {
console.error('FCM 토큰을 가져오는 중 오류가 발생했습니다.');
return null;
}
};
const handleSaveToken = () => {
const fcmToken = sessionStorage.getItem('fcmToken');
console.log(fcmToken);
if (fcmToken) { if (fcmToken) {
saveFcmToken(fcmToken); await saveFcmToken(fcmToken);
console.log(fcmToken);
return;
} }
console.log('저장된 FCM token이 없습니다.');
}; };
const handleTestNotification = () => { const handleTestNotification = async () => {
createTestNotification(); await createFcmNotification()
console.log('ok'); .then(() => {
console.log('테스트 알림에 성공했습니다.');
})
.catch(() => {
console.log('테스트 알림에 실패했습니다.');
});
}; };
handleForegroundMessages();
return ( return (
<div> <div>
<h1 className="heading p-2">hello, firebase!</h1> <h1 className="heading p-2">hello, firebase!</h1>
<div className="p-2"> <div className="p-2">
<Button <Button
onClick={getFcmToken} onClick={handleSaveFcmToken}
variant="outlinePrimary" variant="outlinePrimary"
className="mr-2" className="mr-2"
> >
getFcmToken FCM redis에
</Button>
<Button
onClick={handleSaveToken}
variant="outlinePrimary"
className="mr-2"
>
handleSaveToken
</Button> </Button>
<Button <Button
onClick={handleTestNotification} onClick={handleTestNotification}
variant="outlinePrimary" variant="outlinePrimary"
className="mr-2"
> >
handleTestNotification FCM
</Button> </Button>
</div> </div>
</div> </div>