
이를 통해 앱과 웹사이트로 알림을 쉽게 전송할 수 있으며, 사용자가 앱을 실행하지 않아도 백그라운드에서 중요한 정보를 전달할 수 있다.
Next.js와 같은 웹 애플리케이션 환경에서도 FCM을 사용해 알림 기능을 구현할 수 있다.
pnpm install firebase
firebase-messaging-sw.js 서비스 워커 파일을 프로젝트의 public 폴더에 추가하여 브라우저에서 알림을 수신할 수 있게 합니다.
// /public/firebase-messaging-sw.js
importScripts("https://www.gstatic.com/firebasejs/9.14.0/firebase-app-compat.js");
importScripts("https://www.gstatic.com/firebasejs/9.14.0/firebase-messaging-compat.js");
// FIRE-BASE 앱 등록할때 받은 'firebaseConfig' 값을 넣어주세요.
const config = {
apiKey: "YOUR_API_KEY",
authDomain: "YOUR_AUTH_DOMAIN",
projectId: "YOUR_PROJECT_ID",
storageBucket: "YOUR_STORAGE_BUCKET",
messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
appId: "YOUR_APP_ID",
measurementId: "YOUR_MEASUREMENT_ID",
};
// Initialize Firebase
firebase.initializeApp(config);
const messaging = firebase.messaging();
messaging.onBackgroundMessage((payload) => {
console.log("[firebase-messaging-sw.js] Received background message ", payload);
const { title, body, image, click_action } = payload.data;
self.registration.showNotification(title, { body, image, click_action });
});
self.addEventListener("push", function (event) {
if (event.data) {
// 알림 메세지일 경우엔 event.data.json().notification;
const { title, body, image, click_action } = event.data.json().data;
event.waitUntil(self.registration.showNotification(title, { body, image, data: { click_action } }));
} else {
console.log("This push event has no data.");
}
});
// 클릭 이벤트 처리
self.addEventListener("notificationclick", function (event) {
event.preventDefault();
// 알림창 닫기
event.notification.close();
// 이동할 url
const urlToOpen = event.notification.data.click_action;
// 사이트 열려있는지 체크
const promiseChain = clients
.matchAll({
type: "window",
includeUncontrolled: true,
})
.then(function (windowClients) {
let matchingClient = null;
for (let i = 0; i < windowClients.length; i++) {
const windowClient = windowClients[i];
if (windowClient.url.includes(urlToOpen)) {
matchingClient = windowClient;
break;
}
}
if (matchingClient) {
return matchingClient.focus();
} else {
return clients.openWindow(urlToOpen);
}
});
event.waitUntil(promiseChain);
});
firebaseConfig를 Next.js 클라이언트에 설정하고, FCM 토큰을 요청합니다.
// firebaseConfig.js
import { initializeApp } from "firebase/app";
import { getMessaging, getToken, onMessage } from "firebase/messaging";
const firebaseConfig = {
apiKey: "YOUR_API_KEY",
authDomain: "YOUR_AUTH_DOMAIN",
projectId: "YOUR_PROJECT_ID",
storageBucket: "YOUR_STORAGE_BUCKET",
messagingSenderId: "YOUR_MESSAGING_SENDER_ID",
appId: "YOUR_APP_ID",
};
// Firebase 초기화
const app = initializeApp(firebaseConfig);
// 메시징 초기화
const messaging = getMessaging(app);
export const requestForToken = async () => {
try {
const currentToken = await getToken(messaging, { vapidKey: "YOUR_VAPID_KEY" });
if (currentToken) {
console.log("FCM 토큰:", currentToken);
return currentToken;
} else {
console.log("토큰을 받아올 수 없습니다. 알림 권한을 확인하세요.");
}
} catch (error) {
console.error("토큰 요청 에러:", error);
}
};
export const onMessageListener = () =>
new Promise((resolve) => {
onMessage(messaging, (payload) => {
resolve(payload);
});
});
FCM API에 HTTP POST 요청을 보내려면, 서버 측에서 알림을 보낼 API 엔드포인트를 설정한다.
이 예제에서는 FCM_SERVER_KEY로 Firebase 서버 키를 사용해 FCM에 요청을 전송
// pages/api/sendNotification.ts
import type { NextApiRequest, NextApiResponse } from "next";
const FCM_SERVER_KEY = "YOUR_FCM_SERVER_KEY";
const sendNotification = async (req: NextApiRequest, res: NextApiResponse) => {
const { token, title, body } = req.body;
const message = {
to: token,
notification: {
title,
body,
},
};
const response = await fetch("https://fcm.googleapis.com/fcm/send", {
method: "POST",
headers: {
Authorization: `key=${FCM_SERVER_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(message),
});
if (response.ok) {
res.status(200).json({ success: true, message: "Notification sent successfully" });
} else {
res.status(response.status).json({ success: false, message: "Notification failed" });
}
};
export default sendNotification;
이제 FCM 알림이 설정되었으므로 클라이언트에서 API를 호출해 특정 FCM 토큰으로 알림을 보낼 수 있다.
import { useEffect, useState } from "react";
import { requestForToken, onMessageListener } from "../firebaseConfig";
export default function NotificationComponent() {
const [token, setToken] = useState(null);
const [notification, setNotification] = useState(null);
useEffect(() => {
requestForToken().then((fcmToken) => setToken(fcmToken));
onMessageListener().then((payload) => {
setNotification({
title: payload.notification.title,
body: payload.notification.body,
});
});
}, []);
const sendNotification = async () => {
await fetch("/api/sendNotification", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
token: token,
title: "Test Notification",
body: "This is a test message",
}),
});
};
return (
<div>
<button onClick={sendNotification}>Send Test Notification</button>
{notification && (
<div>
<h2>Notification</h2>
<p>Title: {notification.title}</p>
<p>Body: {notification.body}</p>
</div>
)}
</div>
);
}
FCM의 경우, 너무 잦은 푸시 알림 요청이나 비정상적인 트래픽이 발생하면 Google에서 해당 프로젝트를 제한할 수 있으므로 적절한 빈도와 정책을 준수하는 것이 중요
Firebase 프로젝트 시작하기

프로젝트 이름 생성

동의 후, 프로젝트 만들기



일반 탭 => 하단 내 앱 -> 코드 모양 버튼 클릭

앱 닉네임 설정 후, 앱 생성 클릭하면

SDK 코드 생성

호스팅 설정, 콘솔로 이동



