跳到主要内容

如何在 React 专案中接收 Notification

· 5 分钟阅读
Eric Cheng

一个需求,需要在原来的 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 DevTools 测试

Chrome 设定

Notification 跟的是浏览器,以下只介绍 Chrome

要发通知给使用者必须先得到使用者的授权,我们先看一下 Chrome 的设定在什么地方

到「隐私权与安全性」⇒ 「网站设定」 网站设定 - 隐私权与安全性

可以看到通知 网站设定 - 通知

如果一开始没有授权给其他网站的话,「允许传送通知」列表应该是空白的 网站设定 - 通知2

如何授权

使用的为 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,然后会跳出一个视窗,要求显示通知的权限

Notification 1

点选「允许」后,status 变成 granted

Notification 2

这时候回去看 Chrome 的设定,原来「允许传送通知」的列表,就会多了刚才的 localhost:3000

Notification 3

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」

Push 1

在 log 就可以看到 push 的讯息

Push 2

但使用者是不可能到 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 的小视窗了

Push 3

Continued?

需求大概只完成一半,大致上 client 端可以接收讯息,但还是需要 server 端来发送讯息,方法有不少,比较简单的有像 web-push 的 library, 不过我们用的是 firebase 的 FCM,等有空再来整理笔记吧

版权声明


這是 google 廣告