---
title: Google Service Worker Notifications
tags: Templates, Talk
description: View the slide with "Slide Mode".
---
# Google Service Worker Notifications (通知篇)!
>製作Tinn
>參考:Google各位大大
>[範例參考詳解](https://jonny-huang.github.io/angular/training/21_pwa3/)
---
### Service Workger Notificatoins 分成 push(推送) 與 Notifications(通知)
#### 本邊先來介紹一下 Notification(通知的部分)
- 通知則是瀏覽器上的程式與使用者間的溝通。
- 推送指的是伺服器的後端與瀏覽器上的程式之間的溝通
---
## 環境需求
- production開發環境
- 使用https(可有可無)
- 零食餅乾.......
---
### 瀏覽器通知設定(google chrome為例)
<img src="https://i.imgur.com/KWrRJIR.png">
由此可見瀏覽器通知設定的選項對應至 [Notification API](https://developer.mozilla.org/en-US/docs/Web/API/Notification)的permission屬性
| permission | description |
| -------- | -------- |
| default | 尚未給予權限 (因此不會顯示通知) |
| granted | 允許接收網站的通知 |
| denied | 拒絕接收網站的通知 |
---
### 判斷權限
透過Notification API 可以知道我們可以透過 Notification.requestPermission 檢查權限並於瀏覽器上產生一個允許通知的請求視窗。
<img src="https://i.imgur.com/4HVhe0E.png">
選取允許後 permission變更為 granted了
<img src="https://i.imgur.com/4vlns6u.png">
**請求通知視窗僅**requestPermission.permission**的屬性為**default**才會啟用
若是選取 允許(granted)或是封鎖(denied)後續請求視窗皆不會再次出現**
**若是使用者已選取拒絕、因此可透過Notification.permission判斷權限來確認任狀態並顯示更改通知的視窗**
我們開啟檔案寫入 **requestPermission** 方法
```javascript=
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('./sw.js')
.then(reg => {
// registration worked
console.log('[Service Worker] Registration succeeded. Scope is ' + reg.scope);
if ('Notification' in window) {
console.log('Notification permission default status:', Notification.permission);
Notification.requestPermission(function (status) {
console.log('Notification permission status:', status);
});
}
}).catch(error => {
// registration failed
console.log('[Service Worker] Registration failed with ' + error);
});
}
```
### 顯示通知
處理完權限問題後、我們來實作於畫面上顯示訊息 我們可以透過 ```ServiceWorkerRegistration.showNotification(title, [options]);```方法來呈現
下面是常用的屬性選擇
| option | description |
| -------- | -------- |
| icon | 圖標url |
| body | 內文 |
| image | 圖片 |
| data | 夾帶資料;可於使用者點擊時依照不同的參數去實現不同功能|
| actions | 選單操作 action:識別名稱 ,title:標題, icon:圖標 |
| requireInteraction | false(預設):自動關閉(Chrome 大約20秒後)。 true:訊息一直顯示,直到點擊或是按關閉按鈕才消失。 |
[詳細完整請點這裡](https://developer.mozilla.org/en-US/docs/Web/API/Notification)
捲起袖子把畫面顯示出來吧 內容如下:
```javascript=
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('service-worker.js').then(registration => {
// 注册成功
//console.log('ServiceWorker registration successful with scope: ', registration.scope)
if ('Notification' in window) {
Notification.requestPermission(status => {
console.log('Notification permission status:', status)
if (Notification.permission === 'granted') {
navigator.serviceWorker.getRegistration().then(reg => {
const options = setNotificationOptions();
reg.showNotification('來寫laravel', options)
//console.log('成功發出客戶端通知')
})
}
})
}
}).catch(err => {
// 注册失败
console.log('ServiceWorker registration failed: ', err)
})
}
function setNotificationOptions() {
const options = {
icon: 'https://img.icons8.com/cotton/2x/settings.png',
body: '歡迎來寫laravel喔!!!!!!!',
image: 'https://www.imgglobalinfotech.com/blog/wp-content/uploads/2019/03/6-reasons-why-to-choose-laravel-framework-for-web-development-blog-image858204-768x427.png',
// vibrate: [100, 50, 200], // 震動 僅支援震動的裝置
requireInteraction: true, // 一值停留
data: {
link: 'https://www.laravel-dojo.com/',
link_ok: 'https://laravel.tw/',
link_ng: 'https://learnku.com/articles/5099/why-dont-i-want-to-use-laravel',
},
actions: [{
action: 'yes',
title: '參加',
icon: 'https://img.icons8.com/cotton/2x/settings.png',
},
{
action: 'no',
title: '不參加',
icon: 'https://img.icons8.com/cotton/2x/settings.png',
},
],
}
return options
}
```
---
## 通知顯示時點選參加按鈕
<img src="https://i.imgur.com/cQADZph.gif">
---
## 通知顯示時點選不參加按鈕
<img src="https://i.imgur.com/JDKemPz.gif">
---
## 通知顯示時點選收合時
<img src="https://i.imgur.com/TkY2XRz.gif">
---
## 通知顯示時點選圖片時
<img src="https://i.imgur.com/BTehTpO.gif">
---
### 以上為呈現的結果 、並且將按鈕事件(跳頁)加上去
## **事件監聽的部分必須寫在 ```sw.js```中 以下為範例**
```javascript=
self.addEventListener('notificationclick', function(event) {
const notification = event.notification;
const action = event.action;
const link = notification.data.link;
const link_ok = notification.data.link_ok;
const link_ng = notification.data.link_ng;
switch (action) {
case 'yes':
if (link_ok) {
clients.openWindow(link_ok);
}
break;
case 'no':
if (link_ng) {
clients.openWindow(link_ng);
}
break;
case 'close':
break;
default:
if (link) {
clients.openWindow(link);
}
break;
}
notification.close();
console.log('notificationclick action is', action);
});
```
---
# :100: :muscle: :tada:
## 完成囉下篇再來介紹 push(推送)
---
### Thank you! :sheep: