[FCM] Firebase Cloud Messaging ์ผ๋ก ์น์์ ํธ์์๋ฆผ ๊ตฌํํ๊ธฐ (React ํด๋ผ์ด์ธํธ)
FCM์ด ๋ญ์ง๋ ์ผ๋จ ๋์ค์...
์์ธํ ๊ฒ์ ๐ Firebase Cloud Messaging Documentation์ ๋ฐ๋ผํ๋ฉด ๋ฉ๋๋ค.
์ฐธ๊ณ .
๋จ์ํ ์๋ฒ ์คํ ์์ด http, js ํ์ผ๋ก ์คํํ๋๋ ์๋์ฒ๋ผ ๋จ๋๋ผ๊ณ ์... ์๋ ์ค๋ฅ๋ ์๋ฆผ ๊ถํ ์์ฒญ์ ์ฐจ๋จํ๋ค๋ ๋ฉ์์ง์ธ๋ฐ, file:// ๋๋ฉ์ธ์ผ๋ก ์์ํ๋ฉด ํฌ๋กฌ ์๋ฆผ ์ค์ ์ด ์๋ฌด๋ฆฌํด๋ ํ์ฉ์ด ์๋ฉ๋๋ค.
FirebaseError: Messaging: The notification permission was not granted and blocked instead. (messaging/permission-blocked).
๊ทธ๋์ ๋ฆฌ์กํธ ํด๋ผ์ด์ธํธ๋ก ๋ณ๊ฒฝํด์ ํ ์คํธํด๋ณด๊ธฐ๋ก...
๋์ ์๋ฆฌ
React ํด๋ผ์ด์ธํธ๊ฐ ๋ฉ์์ง ์์ ์ ๋๊ธฐํ๊ณ ์๋ค๊ฐ FCM ์์ ๋ฉ์์ง๋ฅผ ๋ณด๋ด๋ฉด ํธ์ ์๋ฆผ์ ๋์๋๋ค. ์ด๋ ๋ธ๋ผ์ฐ์ ์ Service Worker ๊ฐ ๋ฐฑ๊ทธ๋ผ์ด๋ ์ํ์์ ๋์๊ฐ๋ฉฐ ์ฌ์ดํธ๋ฅผ ๊บผ๋ ํธ์์๋ฆผ์ ๋์ธ ์ ์๊ฒ ํด์ค๋๋ค. ๊ทธ๋ฌ๋ React ํด๋ผ์ด์ธํธ๋ Service Worker ์ ๋ํ ์ค์ ๋ ๊ฐ์ด ํด์ค์ผ ํฉ๋๋ค.
๊ตฌํ
firebase ์ค์น
firebase sdk ๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด firebase ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ถ๊ฐํด์ค๋๋ค.
yarn install firebase
public/firebase-messaging-sw.js
์๋ ์ฝ๋๋ฅผ ์์ฑํ๋ฉด fcm ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์๋์ผ๋ก service worker ๋ฅผ ์ค์ ํด์ค๋๋ค. ๋ฐ๋์ ์ ์ ํ์ผ ๋ฃจํธ ๊ฒฝ๋ก ์๋์ firebase-messaging-sw.js ๋ผ๋ ์ด๋ฆ์ ํ์ผ๋ก ์ ์ฅํด์ฃผ์ด์ผ ํฉ๋๋ค. ๋ ์ ์ ํ์ผ์ด๋ผ ๊ทธ๋ฐ์ง...importScripts ๋ก ํด์ค์ผ ํฉ๋๋ค! ํธ์์๋ฆผ์ด ์ ๋๋ก ๋จนํ์ง ์๋๋ค๋ฉด ํ๋ก์ ํธ importScripts ๋ฌธ์ ํ๋ก์ ํธ ๋ฒ์ ์ ์ต์ ์ผ๋ก ์์ ํด์ฃผ์ธ์. config ๊ฐ์ ํ๋ก์ ํธ ์ค์ > ์ผ๋ฐ ํญ ๋งจ ํ๋จ [๋ด ์ฑ] ์์ ํ์ธ ๊ฐ๋ฅํฉ๋๋ค.
//ํ๋ก์ ํธ ๋ฒ์ ํ์ธ
importScripts("https://www.gstatic.com/firebasejs/9.5.0/firebase-app.js");
importScripts("https://www.gstatic.com/firebasejs/9.5.0/firebase-messaging.js");
const config = {
//ํ๋ก์ ํธ ์ค์ > ์ผ๋ฐ > ํ๋จ์ ๋ด ์ฑ ๋ถ๋ถ ๋ณต์ฌ
};
// Initialize Firebase
firebase.initializeApp(config);
const messaging = firebase.messaging();
//๋ฐฑ๊ทธ๋ผ์ด๋ ์๋น์ค์์ปค ์ค์
messaging.onBackgroundMessage(messaging, (payload) => {
console.log(
"[firebase-messaging-sw.js] Received background message ",
payload
);
// Customize notification here
const notificationTitle = "Background Message Title";
const notificationOptions = {
body: payload,
icon: "/firebase-logo.png",
};
self.registration.showNotification(notificationTitle, notificationOptions);
});
src/util/fcm.js
ํ ํฐ์ ์ป๊ณ ํฌ๊ทธ๋ผ์ด๋ ๋ฉ์์ง ์์ ์ ์ค์ ํ๋ ์ฝ๋์ ๋๋ค. ์ด ํ ํฐ์ ํด๋ผ์ด์ธํธ๋ฅผ ์๋ณํ๋ ๊ฐ์ ๋๋ค. ํ ํฐ์ ์ป๊ธฐ ์ํด์๋ vapid๊ฐ ํ์ํ๋ฐ, ์ด ๊ฐ์ ํ๋ก์ ํธ์ค์ > ํด๋ผ์ฐ๋๋ฉ์์ง > ์น ๊ตฌ์ฑ์ ์นํธ์์ธ์ฆ์ ๋ฐ๊ธ ์์ ๋ฐ๊ธ๋ฐ์ ์ ์์ต๋๋ค. ์ดํ ๋ฆฌ์กํธ ์ฑ์ ์คํํ๋ฉด ์ฝ์์ฐฝ์ ํ ํฐ๊ฐ์ด ์ถ๋ ฅ๋ฉ๋๋ค. ์ฐธ๊ณ ๋ก ์๋น์ค์์ปค์๋ ๋ณ๋๋ก ์ด์ชฝ์์๋ initializeApp ์ ํด์ค์ผ ํฉ๋๋ค.(๊ฑฐ๊ธฐ์๋ง ํ๋ฉด ๋๋ ์ค ์๊ณ ์ํด์คฌ๋๋ uncaught firebaseerror: firebase: no firebase app '[default]' has been created - call firebase app.initializeapp() ์ด๋ฐ ์ค๋ฅ๊ฐ...)
import { initializeApp } from "firebase/app";
import { getMessaging, getToken, onMessage } from "firebase/messaging";
const config = {
//ํ๋ก์ ํธ ์ค์ > ์ผ๋ฐ > ํ๋จ์ ๋ด์ฑ์์ ํ์ธ
};
const app = initializeApp(config);
const messaging = getMessaging();
//ํ ํฐ๊ฐ ์ป๊ธฐ
getToken(messaging, {
vapidKey:
"ํ๋ก์ ํธ์ค์ > ํด๋ผ์ฐ๋๋ฉ์์ง > ์น ๊ตฌ์ฑ์ ์นํธ์์ธ์ฆ์ ๋ฐ๊ธ",
})
.then((currentToken) => {
if (currentToken) {
// Send the token to your server and update the UI if necessary
// ...
console.log(currentToken);
} else {
// Show permission request UI
console.log(
"No registration token available. Request permission to generate one."
);
// ...
}
})
.catch((err) => {
console.log("An error occurred while retrieving token. ", err);
// ...
});
//ํฌ๊ทธ๋ผ์ด๋ ๋ฉ์์ง ์์
onMessage(messaging, (payload) => {
console.log("Message received. ", payload);
// ...
});
src/App.js
fcm ์คํฌ๋ฆฝํธ๋ฅผ app.js ์ ํฌํจ์์ผ์ค๋๋ค.
import "./util/fcm";
...
๋ฉ์์ง ํ ์คํธํ๊ธฐ
firebase ์์ ํ ์คํธํ ์๋ ์๊ณ api ํ ์คํธ ํด๋ก ํ ์คํธํ ์๋ ์์ต๋๋ค.
firebase ์์ ํ ์คํธ
์ฐธ์ฌ > Cloud Messaging > Send your first message ๋ฅผ ์ ํํ ํ ํ ์คํธ ๋ฉ์์ง ์ ์ก์ ๋๋ฆ ๋๋ค.
๋ฆฌ์กํธ ์ฑ ์ฝ์์ฐฝ์ ์ถ๋ ฅ๋ ํ ํฐ๊ฐ์ ์๋์ ์ถ๊ฐํ๊ณ ํ ์คํธ ๋ฒํผ์ ๋๋ฅด๋ฉด ๋ฉ๋๋ค.
ํฌ๊ทธ๋ผ์ด๋ ์ํ์์๋ ์ฝ์์ฐฝ์ ๋ฉ์์ง๊ฐ ์ถ๋ ฅ๋๊ณ , ๋ฐฑ๊ทธ๋ผ์ด๋ ์ํ(์ฌ์ดํธ๋ฅผ ์ข ๋ฃํ๊ฑฐ๋ ๋ค๋ฅธ ํญ์ผ๋ก ์ ํ)์์๋ ์๋์ฒ๋ผ ํธ์ ์๋ฆผ์ด ์ต๋๋ค.
api ํด๋ก ํ ์คํธ
POST ์์ฒญ์ผ๋ก https://fcm.googleapis.com/fcm/send ์๋ํฌ์ธํธ์ ์์ฒญ์ ๋ณด๋ ๋๋ค. header ์๋ Authorization ์ bearer ์ธ์ฆ ํ ํฐ๊ฐ์ ๊ฐ์ด ๋ณด๋ด์ค์ผ ํ๋๋ฐ, ์ด๊ฒ์ ํ๋ก์ ํธ ์ค์ > ํด๋ผ์ฐ๋ ๋ฉ์์ง > ํ๋ก์ ํธ ์ฌ์ฉ์ ์ธ์ฆ ์ ๋ณด์ ์๋ฒํค ํ ํฐ์ ๋ณต์ฌํ์๋ฉด ๋ฉ๋๋ค. bearer์ ๊ทธ ๋ค ๋์ด์ฐ๊ธฐ ๊ผญ ์์ ๋ถ์ฌ์ฃผ์ ์ผ ํฉ๋๋ค. key= ๋ ๊ด์ฐฎ์ต๋๋ค.
send ํ๋ฉด ์๋์ ๊ฐ์ ๊ฒฐ๊ณผ๊ฐ ์ค๊ณ , ํธ์์๋ฆผ์ด ๋น๋๋ค.
api ํด์ด ์๋ค๋ฉด vscode ์์ restclient ํ๋ฌ๊ทธ์ธ์ ์ค์นํ๊ณ test.http ํ์ผ์ ์์ฑํด ์๋์ฒ๋ผ ํ ์คํธํด์ค๋๋ค.
curl --location --request POST 'https://fcm.googleapis.com/fcm/send' \
--header 'Authorization: bearer server-key' \
--header 'Content-Type: application/json' \
--data-raw '{
"notification": {
"title": "TEST",
"body": "์๋ฆผํ
์คํธ"
},
"to": "token"
}'
ํน์ ์ค๋ฅ๊ฐ ๋๋ค๋ฉด ๋ฆฌ์กํธ ์๋ฒ๋ฅผ ์์ ๊ป๋ค๊ฐ ๋ค์ ์คํํด๋ณด์ธ์. ์ ์ ํ์ผ ์์ ์ ์๋ฒ ์ข ๋ฃํ๊ณ ๋ค์ ์คํํด์ผ ์ ๋ฐ์ดํธ ๋ฉ๋๋ค.