到目前為止,我們已介紹如何讓使用者訂閱並傳送推播訊息。接下來,您必須在使用者的裝置上接收這則推播訊息,並顯示通知 (以及執行其他可能需要執行的工作)。
Push 事件
收到訊息後,系統會在服務工作站中發布推送事件。
設定推播事件監聽器的程式碼應與您以 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
則是指工作站本身。
在上述範例中,self.addEventListener()
可視為在服務工作者本身新增事件監聽器。
在推播事件範例中,我們會檢查是否有任何資料,並將內容列印到主控台。
您也可以透過其他方式剖析推播事件的資料:
// 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()
。
Wait Until
關於服務工作站,您必須瞭解的一件事是,您幾乎無法控制服務工作站程式碼的執行時間。瀏覽器會決定何時喚醒及終止該服務。您唯一能向瀏覽器表示「我正忙著處理重要事項」的方法,就是將承諾傳遞至 event.waitUntil()
方法。這樣一來,瀏覽器會持續執行服務 worker,直到您傳入的承諾已完成為止。
對於推播事件,您必須在傳入的承諾已完成時才可顯示通知,這是額外規定。
以下是顯示通知的基本範例:
self.addEventListener('push', function(event) {
const promiseChain = self.registration.showNotification('Hello, World.');
event.waitUntil(promiseChain);
});
呼叫 self.registration.showNotification()
是向使用者顯示通知的方法,並會傳回承諾,在通知顯示後會解析。
為了讓這個範例盡可能清楚,我將這個承諾指派給名為 promiseChain
的變數。然後傳入 event.waitUntil()
。我知道這會產生大量文字,但我發現許多問題都是因為誤解應傳入 waitUntil()
的內容,或是因為承諾鏈條中斷而產生。
以下是較複雜的範例,其中包含網路要求資料,並透過數據分析追蹤推播事件:
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()
,表示瀏覽器會等待兩個承諾完成,然後檢查是否已顯示通知並終止服務工作者。
我們應該關心 waitUntil()
並瞭解如何使用的原因,是因為開發人員面臨的其中一個最常見問題是,當承諾鏈結不正確 / 中斷時,Chrome 會顯示這個「預設」通知:
只有在收到推播訊息,且服務工作者中的推播事件在傳遞至 event.waitUntil()
的承諾完成後「不會」顯示通知時,Chrome 才會顯示「This site has been updated in the background」通知。
開發人員會遇到這個問題的主要原因是,他們的程式碼經常會呼叫 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()
。
在下一節中,我們將探討如何設定通知樣式,以及可顯示的內容。
後續步驟
- 網路推播通知總覽
- 推播通知的運作方式
- 訂閱使用者
- 權限使用者體驗
- 使用網路推送程式庫傳送訊息
- Web Push 通訊協定
- 處理推播事件
- 顯示通知
- 通知行為
- 常見的通知模式
- 推播通知常見問題
- 常見問題和回報錯誤