一個需求,需要在原來的 React PWA 專案中增加接收訊息通知的功能,簡單寫了個筆記,因為需求較複雜了點,還會牽扯 到 firebase,為了單純起見,這篇文章僅僅介紹到 PWA 的 push 和 notification 部份
前置作業
建立 React PWA 專案
之前文章有寫過,簡單再介紹一次,使用 cra-template-pwa 的 template
npx create-react-app test-notification --template cra-template-pwa
在 index.js 有看到一段 code
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://cra.link/PWA
serviceWorkerRegistration.unregister();
將 unregister() 改成 register() 後,執行建置專案然後啟動
npm run build
serve -s build
在 Chrome DevTools 就可以看到 activated and is running
Chrome 設定
Notification 跟的是瀏覽器,以下只介紹 Chrome
要發通知給使用者必須先得到使用者的授權,我們先看一下 Chrome 的設定在什麼地方
到「隱私權與安全性」⇒ 「網站設定」
可以看到通知
如果一開始沒有授權給其他網站的話,「允許傳送通知」列表應該是空白的
如何授權
使用的為 Notification API:官方說明,不仔細說明,可以直接看官方網站
要求授權使用的 function 為 Notification.requestPermission,permission 有三種 status
- default:初使預設值,使用者尚未給予任何權限
- granted:使用者允許接收到網站的通知
- denied:使用者拒絕接收網站的通知
因為我們使用的是 cra-template-pwa 建出來的專案,所以會有這兩個檔案:service-worker.js、serviceWorkerRegistration.js
要求授權
在 serviceWorkerRegistration.js 最後增加以下 code
// 要求 notification 授權
if ('Notification' in window) {
console.log('Notification.permission:' + Notification.permission);
if (Notification.permission != 'granted') {
console.log('Ask user permission')
Notification.requestPermission(status => {
console.log('Status:' + status)
});
}
}
從 log 可以看到一開始的 permission 是 default,然後會跳出一個視窗,要求顯示通知的權限
點選「允許」後,status 變成 granted
這時候回去看 Chrome 的設定,原來「允許傳送通知」的列表,就會多了剛才的 localhost:3000
Push 訊息
來測試一下怎麼 push 訊息
程式部份在 service-worker.js 最後可以看到說明:// Any other custom service worker logic can go here.,所以就不用客氣了,在後面增加我們測試監聽 push 用的 code
// 監聽 push
self.addEventListener('push', (event) => {
console.log( 'push', event);
});
在 Chrome DevTools 點擊「Push」
在 log 就可以看到 push 的訊息
但使用者是不可能到 console 去看 log 的,還是需要有顯示出來的視窗才符合需求,改寫一下
// 監聽 push
self.addEventListener('push', (event) => {
console.log('push', event);
let title = 'Server Push';
let options = {
body: 'Push Test',
icon: '/logo192.png'
};
event.waitUntil(self.registration.showNotification(title, options));
});
同樣在 Chrome DevTools 點擊「Push」,這時右下角就會跳出一個寫著 Server Push 的小視窗了
Continued?
需求大概只完成一半,大致上 client 端可以接收訊息,但還是需要 server 端來發送訊息,方法有不少,比較簡單的有像 web-push 的 library, 不過我們用的是 firebase 的 FCM,等有空再來整理筆記吧