iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 22
3

為何PWA需要推播通知(Push Notifications)


首先,只要用戶允許我們推播,當有新的貼文資訊時,我們就可以主動通知用戶。即使今天用戶關閉網頁或是根本沒在用手機,瀏覽器的background process(也就是service worker)也會繼續運行,我們可以透過service worker來接收傳入的推播通知。

推播服務對網頁的影響是非常大的,因為它允許我們在「用戶沒有使用應用程式的情況」來與用戶溝通。

推播通知的另一個核心功能是,即使用戶沒有積極地在使用我們的應用程式,我們還是有管道能與用戶來聯繫,這讓我們有機會將用戶帶回到我們的應用程式中。這是過去android或ios的原生APP才有的一個主要優勢,現在我們也可以在PWA中利用它。

推播(Push Notifications)的流程

  1. 一開始用戶必須先允許開啟推播通知,這樣才能繼續享用推播的服務。
  2. service worker會確認有哪些用戶允許推播通知,這邊把它稱之為訂閱(subscription)。特別說一下這裡的訂閱是由browse進行管理的,也就是說不同的browser都可以去訂閱我們的PWA。
  3. 如果用戶過去從沒有訂閱過,那就在service worker中建立一個新的subscription。
  4. 這個新的subscription會自動去向「瀏覽器供應商(像Google、Mozilla)的push server」發出請求一個,推送伺服器會回傳一個url和其他資訊,而之後會將推送的訊息傳送至這個url(API Endpoint)。
  5. 當然我們也必須要有一個自己的後台Server(這裡我是使用Firebase Cloud Funcitons),將訂閱用戶的資訊儲存到後台firebase資料庫中。
  6. 當訂閱的用戶發佈新貼文時,我的後台Server就會推送這個訊息和一些驗證資訊到「從瀏覽器供應商取得的API Endpoint」。
  7. 同時service worker會一直監聽push事件,當瀏覽器供應商的push server傳送推播訊息時會被觸發。
  8. 最後service worker就會將推播訊息通知給用戶。

在實作之前必須先了解「顯示通知(Display Notification)」的基本概念:

雖然在我的流程中是透過service worker監聽push事件,來決定是否要顯示推播通知。不過事實上並不一定要透過service worker才能顯示通知,透過一般的javascript就可以實作,這裡要使用的就是「Notification API」來創建並顯示推播通知。

來開始實作要怎麼讓用戶「允許顯示通知」吧:/images/emoticon/emoticon08.gif
在左邊的sidebar中可以看到一個訂閱鈕,這裡我想讓用戶按下按鈕後會跳出是否「允許顯示通知」的視窗。首先要來確認瀏覽器是否支援Notification API,若有的話則這個訂閱鈕才會出現。

一開始在app.css中將這個訂閱鈕隱藏起來:

.enable-notifications {
  display: none;
}

接著在app.js中加入上面我說的邏輯:

function askForNotificationPermission() {
    Notification.requestPermission(function(result) {
        // 這裡result只會有兩種結果:一個是用戶允許(granted),另一個是用戶封鎖(denied)
        console.log('User Choice', result);
        if(result !== 'granted') {
            console.log('No notification permission granted!');
        } else {
            displayConfirmNotification();
        }
    });
}

if('Notification' in window) {
    for(var i=0; i<enableNotificationButtons.length; i++) {
        enableNotificationButtons[i].style.display = 'inline-block';
        enableNotificationButtons[i].addEventListener('click', askForNotificationPermission);
    }
}

這邊重點是askForNotificationPermission()這個funciton,使用Notification提供的requestPermission() method來去向用戶請求「是否允許顯示通知」。之後透過一個callback function,針對用戶的選擇進行對應的處理。目前我只處理了若用戶「封鎖通知」,會印出一個"No notification permission granted!"。

按下訂閱button後的結果:

我剛剛還沒實作「用戶允許顯示通知的情況下」要進行的處理(也就是displayConfirmNotification函式):

function displayConfirmNotification() {
    var options = {
        body: '您已成功訂閱我們的推播服務!'
    }
    new Notification('成功訂閱!!', options);
}

當用戶按下允許後,電腦就會跳出「成功訂閱」的系統通知,另外我們也可以設定一些額外的選項,這裡我就先簡單的設定body的內容。看一下系統的「顯示通知畫面」會是如何:


目前「顯示通知(Display Notification)」都是在一般的js code裡實現,不過在前面的推播流程中可以知道,我主要是想在service worker裡監聽push event並顯示通知。所以我要修改一下displayConfirmNotification()這個函式,希望能透過service worker來去執行「顯示通知」的動作:

function displayConfirmNotification() {
    if('serviceWorker' in navigator) {
        var options = {
            body: '您已成功訂閱我們的推播服務!'
        }
        navigator.serviceWorker.ready.then(function(swreg) {
            swreg.showNotification('成功訂閱!! (from Service Worker)', options);
        });
    }
}

首先,先確認瀏覽器支援service worker。之後當service worker activate後,使用ready這個property回傳一個promise,在promise裡可以根據它回傳結果(swreg)去操作這個已經註冊完成的service worker。

這裡除了在sw.js中可以操作service worker外,又學到了另一個操作service worker的方法XDD

接著使用service worker中提供的showNotification() interface來顯示通知。輸入的內容基本上就是跟前面相同,不過為了避免跟前面的實作便搞混,我把通知的title多加了(form Service Worker),代表這是從service worker發出的通知訊息,而不是一般的js code。

Day22 結束!! /images/emoticon/emoticon07.gif


上一篇
[Day21] 了解PWA中的背景同步(Part3)
下一篇
[Day23] 實作PWA推播通知(Part2)
系列文
你應該要知道的新一代Web技術---漸進式網頁(PWA)29
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言