一个需求,需要在原来的 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,等有空再来整理笔记吧