---
# System prepended metadata

title: Google Service Worker Notifications
tags: [' Talk', Templates]

---

---
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: 
