現在,我們介紹了使用者的訂閱流程,並傳送推送訊息。下一步是在使用者的裝置上接收此推送訊息,並顯示通知 (以及其他我們想要執行的作業)。
推送事件
接收訊息後,系統就會在您的服務工作處理程序中分派推送事件。
設定推送事件監聽器的程式碼應與您用 JavaScript 編寫的任何其他事件監聽器類似:
self.addEventListener('push', function(event) {
if (event.data) {
console.log('This push event has data: ', event.data.text());
} else {
console.log('This push event has no data.');
}
});
對大多數服務工作站新手開發人員而言,這段程式碼的最古老是 self
變數。self
經常用於網路工作站,也就是 Service Worker。self
是指全域範圍,就像網頁中的 window
一樣。但如果是網路工作站和 Service Worker,self
指的是 worker 本身。
在上述範例中,self.addEventListener()
可視為為 Service Worker 新增事件監聽器。
在推送事件範例中,我們會檢查是否有任何資料,並將內容輸出至控制台。
您還可以透過其他方式剖析推送事件的資料:
// Returns string
event.data.text()
// Parses data as JSON string and returns an Object
event.data.json()
// Returns blob of data
event.data.blob()
// Returns an arrayBuffer
event.data.arrayBuffer()
大部分人會使用 json()
或 text()
,取決於他們希望應用程式得到的內容。
本範例說明如何新增推送事件監聽器,以及如何存取資料,但缺少兩項功能。未顯示通知,也沒有使用 event.waitUntil()
。
等待時間:
需要瞭解的其中一個事項是,您無法控制服務工作站程式碼何時執行。瀏覽器會判斷喚醒時間和終止時間的時間。您可以藉由將承諾傳遞至 event.waitUntil()
方法,讓瀏覽器知道「嘿,我很忙,忙著處理重要工作」。如此一來,瀏覽器就會讓 Service Worker 持續運作,直到您傳入的承諾會維持不變為止。
使用推送事件時,您必須另外顯示通知,才能保證傳入的 promise。
以下是顯示通知的基本範例:
self.addEventListener('push', function(event) {
const promiseChain = self.registration.showNotification('Hello, World.');
event.waitUntil(promiseChain);
});
呼叫 self.registration.showNotification()
的方法可向使用者顯示通知,並會傳回承諾在顯示通知後立即解決的問題。
為了讓這個範例盡可能清楚明瞭,我已經將這個承諾項目指派給名為 promiseChain
的變數。這會傳遞至 event.waitUntil()
。我知道這部分非常冗長,但我發現許多問題因為誤解了應傳遞至 waitUntil()
中,或是因為已毀損的 Proto 鏈而造成的。
這類範例比較複雜,像是提出資料網路要求,以及利用數據分析追蹤推送事件,如下所示:
self.addEventListener('push', function(event) {
const analyticsPromise = pushReceivedTracking();
const pushInfoPromise = fetch('/api/get-more-data')
.then(function(response) {
return response.json();
})
.then(function(response) {
const title = response.data.userName + ' says...';
const message = response.data.message;
return self.registration.showNotification(title, {
body: message
});
});
const promiseChain = Promise.all([
analyticsPromise,
pushInfoPromise
]);
event.waitUntil(promiseChain);
});
我們在此呼叫一個傳回承諾 pushReceivedTracking()
的函式,為了達到這個範例,可以假定會向我們的分析供應商發出網路要求。我們也會發出網路要求,取得回應,並使用通知標題與訊息的回應資料來顯示通知。
我們可以結合這些承諾與 Promise.all()
,確保服務工作站在執行這兩項工作時保持運作。結果保證會傳遞至 event.waitUntil()
,這表示瀏覽器會等到兩次承諾都完成後,才會檢查通知是否已顯示,並終止 Service Worker。
我們應該要重視 waitUntil()
和使用方式,因為開發人員最常遇到的其中一個問題是,入侵鏈結不正確 / 無效時,Chrome 會顯示這則「預設」通知:
![Chrome 預設通知的圖片](https://web.developers.google.cn/static/articles/push-notifications-handling-messages/image/an-image-the-default-not-ec0a0feda0315.png?authuser=9&hl=zh-tw)
Chrome 只會顯示「這個網站已在背景更新過」通知。當收到推送訊息時,服務工作處理程序中的推送事件也不會在承諾傳遞至 event.waitUntil()
時顯示通知。
開發人員被發現,主要是因為他們的程式碼通常會呼叫 self.registration.showNotification()
,但「並未」執行任何承諾傳回時的行為。這會間歇性導致顯示預設通知。舉例來說,我們可以移除上例中 self.registration.showNotification()
的傳回,而收到這則通知的風險。
self.addEventListener('push', function(event) {
const analyticsPromise = pushReceivedTracking();
const pushInfoPromise = fetch('/api/get-more-data')
.then(function(response) {
return response.json();
})
.then(function(response) {
const title = response.data.userName + ' says...';
const message = response.data.message;
self.registration.showNotification(title, {
body: message
});
});
const promiseChain = Promise.all([
analyticsPromise,
pushInfoPromise
]);
event.waitUntil(promiseChain);
});
看看它有多容易錯過的事物。
提醒您,如果看到這則通知,請查看承諾鏈和 event.waitUntil()
。
在下一節中,我們將探討如何為通知設定樣式,以及可以顯示的內容。