Firebase feat React 簡易教學 (二):在網頁接收 Messaging
· 5 分鐘閱讀
Firebase 系列文的第二篇,之前寫過【如何在 React 專案中接收 Notification】,這篇文章有點像,只是不使用 cra-template-pwa,而是完全的只用 Firebase 提供的功能
前置作業
如果還沒有建置專案及安裝 Firebase SDK 的話,請先參考【Firebase feat React 簡易教學 (一):簡介&快速 hosting 新網站】
產生 雲端通訊 網路推播憑證金鑰
到「專案設定」=>「雲端通訊」
到「網路設定」=>「網路推播憑證」,點選「Generate key pair」

裝會產生一個金鑰組

然後同樣在 App.js 加入以下 code
import { getMessaging, getToken } from "firebase/messaging";
// messaging
const messaging = getMessaging();
const vapidKey = 'BHweFH.......................'
getToken(messaging, { vapidKey: vapidKey }).then((currentToken) => {
if (currentToken) {
// 取得 currentToken,需傳回 server
console.log('get currentToken');
console.log(currentToken);
} else {
console.log('No registration token available. Request permission to generate one.');
}
}).catch((err) => {
console.log('An error occurred while retrieving token. ', err);
});
- vapidKey 就是剛才產生的金鑰組
- 這份程式會印出 currentToken 的值,這個值每個使用者每個瀏覽器都不一樣,一般來說要把這個值傳回 server 存起來,然後再依照存下來的 token 發送訊息,這裏簡化起見,僅先印出來
打開專案首頁,叫出 Chrome DevTools,就可以看到印出來的 token

建立 Listener
Firebase 有自己的 service worker,檔名叫做firebase-messaging-sw.js,位置在根目錄下,這裏踩了點雷,需要注意
- 這個檔案不會自動產生,需要手動建立,然後根目錄以 React 來說,就是放在 public 目錄下,而非 src 目錄
- 因為不是放在 src 下,所以語法不太一樣,不能直接用 import ...etc
將以下程式寫入 firebase-messaging-sw.js,這段程式會去監聽 BackgroundMessage,也就是只要瀏覽器開著,即使沒上連上網站,也能收到訊息
// Scripts for firebase and firebase messaging
importScripts('https://www.gstatic.com/firebasejs/8.2.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/8.2.0/firebase-messaging.js');
const firebaseConfig = {
....
};
firebase.initializeApp(firebaseConfig);
// Retrieve firebase messaging
const messaging = firebase.messaging();
messaging.onBackgroundMessage(function (payload) {
console.log('Received background message ', payload);
});
然後 App.js 也增加以下 code,這段程式會監聽在網站開啟時,傳送訊息會在左下角跳出小視窗
import { onMessage } from "firebase/messaging";
onMessage(messaging, (payload) => {
console.log('Message received. ', payload);
const notificationTitle = 'Message Title';
const notificationOptions = {
body: 'Message body.',
icon: '/logo192.png'
};
new Notification(notificationTitle, notificationOptions)
});
