こんにちは この短い記事では、サイトにプッシュ通知を迅速かつ簡単に設定する方法を説明します。 この記事は網羅的なガイドではありませんが、今後の研究の出発点となることを願っています。
このトピックに関する多くの情報はインターネット上にありますが、断片化され、さまざまなリソースに散らばり、Java、C ++、Pythonの例を含むモバイルデバイスの通知と混ざっています。 私たちは、Web開発者としてJavaScriptに興味があります。 この記事では、すべての必要かつ有用な情報を蓄積しようとします。
プッシュ通知が何であるかを既に知っていると思いますが 、それでも主なことについて簡単に説明します。
サイトに入るユーザーは、そこからデータを取得します。 これは便利で安全ですが、インターネットリソースの開発に伴い、ユーザーが要求するのを待たずに、ユーザーに情報を迅速に配信する必要があります。 そのため、サーバーからクライアントへのデータのプッシュ配信のテクノロジーが登場しました。
重要です
プッシュ通知は、サイトにHTTPSがある場合にのみ機能します。
有効なSSL証明書がないと、機能しません。 したがって、HTTPSのサポートがまだない場合は、それを実行する時間です。 Let's Encryptの使用をお勧めします。
ローカルホストで実行するには、 トリックに頼る必要があります。 Github Pagesでスクリプトをテストしました。
目次
良い通知
プッシュ通知は広告メール用ではないことをすぐに予約したいと思います。 特定のユーザーが本当に必要とするものと、彼が本当に迅速に応答する必要があるものだけを送信する必要があります。
良い例:
- テクニカルサポートに連絡するユーザーのステータスの変更に関する通知を送信する。
- 注文ステータスの変更に関する通知の送信。
- ユーザーが待っていた商品の倉庫内の外観。
- 記事に対するユーザーのコメントに返信しました。
- バグまたはクリティカルステータスのバグトラッカーの新しいタスク。
悪い例:
- 倉庫への新規到着。
- 商品の割引とプロモーション;
- サイト上の新しい記事。
- 彼らは1年前に彼が書いた記事に対するユーザーのコメントに応答しました。
悪い例でも通知が必要ですが、迅速に対応する必要はありません。 これらの通知はメールで送信できます。 一般に、プッシュ通知は制御できないさまざまな理由でユーザーに届かない可能性があるため、すべての重要な通知を電子メールで複製することをお勧めします。 もう1つの重要な要素は、イベントの関連性です。 これについては後で説明します。 読むことをお勧めします:
羊に戻りましょう。 それでは、どのように機能しますか? まず、少しの理論。
理論
初心者の中では、プッシュ通知は特別なリソースを実装する必要のない単純な技術であるという意見があります。 実際には、これはテクノロジーのプール全体です。
はじめに、それがどのように機能するかについての小さなアウトライン( アニメーションレイアウト ):
- サーバーはユーザーにページを提供します。
- クライアントはメッセージサーバーに接続し、IDを登録および受信します。
- クライアントは受信したIDをサーバーに送信し、サーバーはデバイスIDを使用して特定のユーザーを特定のデバイスにバインドします。
- サーバーは、以前に受信したIDを使用して、メッセージサーバーを介してクライアントにメッセージを送信します。
残念ながら、誰がどのようにデバイスIDを作成し、メッセージサーバーが特定のデバイスにどのように接続されているかを知ることができませんでした。 GoogleのFirebase Cloud Messagingメッセージサーバーとそのライブラリを使用しました。 残念ながら、サーバーに置き換えることができるかどうか、およびその方法を理解できませんでした。
楽しい事実
最初に、使用されるメッセージを送信するには:
クラウドからデバイスへのメッセージング
その後、次のものに置き換えられました。
Googleクラウドメッセージング
そして、再び次のように変更されました。
Firebaseクラウドメッセージング
次は何だろう。
クライアント側で何が起こりますか?
- JavaScriptは、ユーザーに通知を表示する許可を求めます。
- ユーザーが承認した場合、メッセージサーバーに接続してデバイスIDを取得します。
- ユーザーを識別するために、サーバーに識別子を送信します。
- バックグラウンドで動作するJavaScript ワーカーを初期化し、メッセージサーバーからメッセージを受信してユーザーに表示します。
- メッセージサーバーに接続し、新しい到着を待っています。
ご注意
Google は 、スイッチを使用して通知を購読および購読解除することをお勧めします。 したがって、通知サブスクリプションプロセスの開始は、サイトからではなく、ユーザーから行われます。
各着信ユーザーの通知にサインアップを強制することは悪い習慣です。 そうしないでください。
すべて非常に複雑に見えますが、サーバー上ではすべてが単純ではありません。
サーバー側の問題
- ユーザーが送信したデバイス識別子をデータベースに保存することは明らかです。
- デバイス識別子は、パーソナライズされたメッセージを送信するためにユーザーにバインドするとよいでしょう。
- 1人のユーザーがいて、彼は複数のデバイスを持つことができ、複数のユーザーが1つのデバイスを使用できることを思い出してください。
- ユーザーへの通知の送信は最も安価な操作ではないため、通知の送信をトリガーするイベントは送信用のキューに入れる必要があります。
- 同じHTTPリクエスト中にイベント通知を送信する余裕があるのは、受信者の数が少ない小規模プロジェクトのみです。
- したがって、RabbitMQ、Redisなどのキューイングシステムがあります。
- キューおよびその他のキューサポートツールを解析するデーモン/ワーカーが表示されます。
- 送信速度を上げるには、プロセスを並列化し、複数のノードに分散できます。
練習する
最後に、最も重要なことに移りました。 前述のとおり、 Firebase Cloud Messagingをメッセージサーバーとして使用するため、Firebaseでプロジェクトを登録および作成することから始めます。
ここではすべてが簡単です:
- 私たちはサイトに行きます 。
- 登録済みです。
- プロジェクトが既にある場合は、[ 新しいプロジェクトを作成 ]または[ Googleプロジェクトをインポート ]ボタンをクリックします 。
- 作成するときに、プロジェクトの名前と国を指定します。
- プロジェクトを作成すると、そのダッシュボードが表示されます。
- メニューで、[ 概要 ]の横にあるホイールを移動し、[ プロジェクト設定 ]を選択します 。
- 開いたページで、[ クラウドメッセージング ]タブに移動します。
- サーバーからメッセージを送信するために使用されるServer keyと、クライアント側でメッセージを受信するために使用されるSender IDに興味があります 。
あなたはまだ設定を掘り下げてアクセス権の分離で遊ぶことができますが、一般に、Firebaseサイトでの作業は終わりました。
クライアントの作成を開始する
プッシュ通知を受信するService Workerを作成することから始めましょう。
次の内容のfirebase-messaging-sw.jsファイルを作成します。
// firebase-messaging-sw.js importScripts('https://www.gstatic.com/firebasejs/3.6.8/firebase-app.js'); importScripts('https://www.gstatic.com/firebasejs/3.6.8/firebase-messaging.js'); firebase.initializeApp({ messagingSenderId: '<SENDER_ID>' }); const messaging = firebase.messaging();
どこで
-
<SENDER_ID>
は、Firebaseへの登録後に受け取った送信者IDです。
重要なお知らせ
Service Workerファイルはfirebase-messaging-sw.jsと正確に呼ばれる必要があり、プロジェクトのルートに配置する必要があります 。つまり、 https: //example.com/firebase-messaging-sw.jsで利用可能です。 このファイルへのパスは、 Firebase ライブラリにハードコーディングされています 。
作成されたコードは、通知を表示するのに十分です。 追加機能については少し後で説明します。 次に、Firebaseライブラリとサブスクリプションスクリプトをページテンプレートに追加します。
<script type="text/javascript" src="//www.gstatic.com/firebasejs/3.6.8/firebase.js"></script> <script type="text/javascript" src="/firebase_subscribe.js"></script>
通知をサブスクライブするボタンをページに追加します
<button type="button" id="subscribe"> </button>
通知を購読する
// firebase_subscribe.js firebase.initializeApp({ messagingSenderId: '<SENDER_ID>' }); // // , Firebase, if ('Notification' in window) { var messaging = firebase.messaging(); // // if (Notification.permission === 'granted') { subscribe(); } // , // $('#subscribe').on('click', function () { subscribe(); }); } function subscribe() { // messaging.requestPermission() .then(function () { // ID messaging.getToken() .then(function (currentToken) { console.log(currentToken); if (currentToken) { sendTokenToServer(currentToken); } else { console.warn(' .'); setTokenSentToServer(false); } }) .catch(function (err) { console.warn(' .', err); setTokenSentToServer(false); }); }) .catch(function (err) { console.warn(' .', err); }); } // ID function sendTokenToServer(currentToken) { if (!isTokenSentToServer(currentToken)) { console.log(' ...'); var url = ''; // ID $.post(url, { token: currentToken }); setTokenSentToServer(currentToken); } else { console.log(' .'); } } // localStorage , // function isTokenSentToServer(currentToken) { return window.localStorage.getItem('sentFirebaseMessagingToken') == currentToken; } function setTokenSentToServer(currentToken) { window.localStorage.setItem( 'sentFirebaseMessagingToken', currentToken ? currentToken : '' ); }
以上です。 これは、プッシュ通知を受信するために必要なすべてのコードです。
サーバーから通知を送信する
一般に、通知の送信は次のようになります。
POST /fcm/send HTTP/1.1 Host: fcm.googleapis.com Authorization: key=YOUR-SERVER-KEY Content-Type: application/json { "notification": { "title": "", "body": " 21:00", "icon": "https://eralash.ru.rsz.io/sites/all/themes/eralash_v5/logo.png?width=40&height=40", "click_action": "http://eralash.ru/" }, "to": "YOUR-TOKEN-ID" }
どこで
-
YOUR-SERVER-KEY
は、Firebaseへの登録時に受け取ったサーバーキーです。 -
YOUR-TOKEN-ID
は、特定のユーザーのデバイスIDです。
順番にすべてのフィールド:
-
notification
-notification
パラメーター。 - title-通知のタイトル。 30文字に制限します。
-
body
テキスト通知。 120文字に制限されています。 -
icon
通知アイコン。 アイコンのサイズにはいくつかの標準がありますが、192x192を使用しています。 小さいアイコンはモバイルデバイスでは見栄えがよくありません。 -
click_action
通知をクリックしてユーザーがアクセスするページのURLアドレス。 - to-通知の受信者のデバイスID。
- オプションの全リストはこちら 。
これは、1人の受信者に1つの通知を送信する例です。 1つの通知を複数の受信者に一度に送信できます。 一度に最大1000人の受信者。
{ "notification": { "title": "", "body": " 21:00", "icon": "https://eralash.ru.rsz.io/sites/all/themes/eralash_v5/logo.png?width=192&height=192", "click_action": "http://eralash.ru/" }, "registration_ids": [ "YOUR-TOKEN-ID-1", "YOUR-TOKEN-ID-2" "YOUR-TOKEN-ID-3" ] }
メッセージサーバーからの応答の例:
{ "multicast_id": 6407277574671070000, "success": 1, "failure": 0, "canonical_ids": 0, "results": [ { "message_id": "0:1489072146895227%e609af1cf9fd7ecd" } ] }
{ "multicast_id": 7867877497742898000, "success": 1, "failure": 0, "canonical_ids": 0, "results": [ { "message_id": "https://updates.push.services.mozilla.com/m/gAAAAABYwWmlTCKje5OLwedhNUQr9LbOCmZ0evAF9HJBnR-v7DF2KEkZY3zsT8AbrqB6JfJO6Z6vsotLJMmiIvJs9Pt1Q9oc980BRX2IU1-jlzRLIhSVVBLo2i80kBvTMYadVAMIlSIyFkWm-qg_DfLbenlO9z1S4TGMJl0XbN5gKMUlfaIjnX2FBG4XsQjDKasiw8-1L38v" } ] }
{ "multicast_id": 8165639692561075000, "success": 0, "failure": 1, "canonical_ids": 0, "results": [ { "error": "InvalidRegistration" } ] }
エラーコードの完全なリスト。
特定のプログラミング言語に縛られることはありません。サンプルを簡単にするために、cURL拡張機能付きのPHPを使用します。 通知送信スクリプトは、コンソールから実行する必要があります。
#!/usr/bin/env php <?php $url = 'https://fcm.googleapis.com/fcm/send'; $YOUR_API_KEY = ''; // Server key $YOUR_TOKEN_ID = ''; // Client token id $request_body = [ 'to' => $YOUR_TOKEN_ID, 'notification' => [ 'title' => '', 'body' => sprintf(' %s.', date('H:i')), 'icon' => 'https://eralash.ru.rsz.io/sites/all/themes/eralash_v5/logo.png?width=192&height=192', 'click_action' => 'http://eralash.ru/', ], ]; $fields = json_encode($request_body); $request_headers = [ 'Content-Type: application/json', 'Authorization: key=' . $YOUR_API_KEY, ]; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers); curl_setopt($ch, CURLOPT_POSTFIELDS, $fields); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); $response = curl_exec($ch); curl_close($ch); echo $response;
messaging.onMessage
messaging.onMessage
ハンドラーは、落とし穴のカテゴリーに属しているため、特に言及する価値があります。 Firebaseの例では、このハンドラーを使用した例を見ていません。 私はFluorescentHallucinogenによってそれについて話されました、彼に特別な感謝をしますが、彼はその使用のいくつかの特徴に言及しませんでした。
これはどのようなハンドラーで、どのように機能しますか。 ドキュメントから、プッシュ通知を受信するとこのハンドラーが呼び出され、その時点で通知が送信されたサイト(ネイティブソリューションを使用したい人は実装例を参照できます)にあることがわかります。 この機能は、美しいモーダルなどを作成してページに通知を表示できるという点で非常に便利です。 そのようなニーズはないので、 標準の通知を表示します。
if ('Notification' in window) { var messaging = firebase.messaging(); messaging.onMessage(function(payload) { console.log('Message received. ', payload); new Notification(payload.notification.title, payload.notification); }); // ... } // ...
すべてがシンプルに思えますが、落とし穴があります。 問題は、モバイルデバイスでは、Notificationコンストラクターの使用が禁止されていることです。 この問題を解決するには、 ServiceWorkerRegistration.showNotification()
を使用する必要があり、この場合のハンドラーは次のようになります。
// ... messaging.onMessage(function(payload) { console.log('Message received. ', payload); // ServiceWorker navigator.serviceWorker.register('messaging-sw.js'); // Notification.requestPermission(function(result) { if (result === 'granted') { navigator.serviceWorker.ready.then(function(registration) { // return registration.showNotification(payload.notification.title, payload.notification); }).catch(function(error) { console.log('ServiceWorker registration failed', error); }); } }); }); // ...
通知は、モバイルデバイスで機能するようになりました。 それはすべてのように見えますが、そうではありません。 一部の保証にもかかわらず、ServiceWorkerは空にしないでください。 ユーザーがクリックする必要のあるページをクリックするようにします。 これを行うには、ServiceWorkerに通知クリックハンドラーを追加する必要があります。
click_action
プロパティにアクセスするための通知設定を保存します。
// ... navigator.serviceWorker.ready.then(function(registration) { payload.notification.data = payload.notification; // registration.showNotification(payload.notification.title, payload.notification); }).catch(function(error) { console.log('ServiceWorker registration failed', error); }); // ...
ServiceWorkerで通知クリックを処理します。
// messaging-sw.js self.addEventListener('notificationclick', function(event) { const target = event.notification.data.click_action || '/'; event.notification.close(); // // , event.waitUntil(clients.matchAll({ type: 'window', includeUncontrolled: true }).then(function(clientList) { // clientList - !? for (var i = 0; i < clientList.length; i++) { var client = clientList[i]; if (client.url == target && 'focus' in client) { return client.focus(); } } // return clients.openWindow(target); })); });
TTLおよび追加の通知制御
通知のための重要なプロパティは、その関連の時間かもしれません。 それはビジネスプロセスに依存します。 デフォルトでは、通知の有効期間は4週間です。 これは、この種の通知には多くの機能があります。 たとえば、「お気に入りの番組は15分後に開始します」という通知は、15分間関連しています。 その後、メッセージは関係ないため表示されません。 0〜2419200秒の値を持つtime_to_live
プロパティは、ライフタイムの制御を担当します。 詳細はドキュメントをご覧ください。 指定されたTTLを持つメッセージは次のようになります。
{ "notification": { "title": "", "body": " 15 ", "icon": "https://eralash.ru.rsz.io/sites/all/themes/eralash_v5/logo.png?width=192&height=192", "click_action": "http://eralash.ru/" }, "time_to_live": 900, "to": "YOUR-TOKEN-ID" }
「お気に入りの番組は15分で開始します」などのメッセージは15分間関連していますが、送信後1分以内に不正確になります。 転送は15分後ではなく14分後に開始されるため、このような状況はクライアント側で制御する必要があります。
これを行うには、サーバーから送信されるメッセージを変更します。
{ "data": { "title": "", "time": 1489006800, "icon": "https://eralash.ru.rsz.io/sites/all/themes/eralash_v5/logo.png?width=192&height=192", "click_action": "http://eralash.ru/" }, "time_to_live": 900, "to": "YOUR-TOKEN-ID" }
notification
フィールドがdata
変更されていることに注意してください。 これで、デフォルトのFirebaseハンドラーは呼び出されなくなり、独自にこれを行う必要があります。 firebase-messaging-sw.js
の最後に次の行を追加しfirebase-messaging-sw.js
。
// messaging.setBackgroundMessageHandler(function(payload) { if (typeof payload.data.time != 'undefined') { var time = new Date(payload.data.time * 1000); var now = new Date(); if (time < now) { // return null; } var diff = Math.round((time.getTime() - now.getTime()) / 1000); // // : " 14 , 21:00" payload.data.body = ' ' + Math.round(diff / 60) + ' , ' + time.getHours() + ':' + (time.getMinutes() > 9 ? time.getMinutes() : '0' + time.getMinutes()) ; } // data payload.data.data = payload.data; // return self.registration.showNotification(payload.data.title, payload.data); }); // self.addEventListener('notificationclick', function(event) { // const target = event.notification.data.click_action || '/'; event.notification.close(); // // , event.waitUntil(clients.matchAll({ type: 'window', includeUncontrolled: true }).then(function(clientList) { // clientList - !? for (var i = 0; i < clientList.length; i++) { var client = clientList[i]; if (client.url == target && 'focus' in client) { return client.focus(); } } // return clients.openWindow(target); })); });
このような簡単な方法で、通知を完全に制御できました。 最も興味深いのは、ユーザーに自分のタイムゾーンで通知時間を表示することです。 これは、世界中で機能するサービスや、母ロシアのようにタイムゾーンが広範囲に広がる地域に当てはまります。
おわりに
さて、悲しいことについて話しましょう。 テクノロジーのすべての魅力にもかかわらず、多くの欠点があります。
- 主な問題は、いつものように、 ブラウザのサポートです。 Chrome、Firefox、Operaの最新バージョンでは完全にサポートされています。 IE、Safari、Opera Mini、UC Browser、Dolphin、およびその他の兄弟は除外されています。 ただし、モバイル版のChrome、Firefox、Operaブラウザーでは機能します。
- オープンサイトと実行中のService Workerは、メッセージ配信を保証しません。 ただし、通知は閉じたブラウザーで発生する場合があります。
Firebaseライブラリは多くの秘密を隠しており、その研究はいくつかの質問に対する答えを提供する可能性がありますが、これはこの記事の範囲外です。
プレイする
GitHub Pagesプロジェクト
Service Workerを起動するにはHTTPSが必要なので、最も簡単な解決策はプロジェクトをGitHub Pagesに置くことでした。
プロジェクトは、 https : //github.com/peter-gribanov/serviceworkerで入手できます。
プロジェクトのソース: https : //peter-gribanov.github.io/serviceworker/
プロジェクトは、通知を送受信するための完全なアプリケーションです。 通知を受信するには、次のことが必要です。
- ページに移動します 。
- [ 登録 ]ボタンをクリックします。
- ブラウザは通知を表示する許可を要求します。
- 許可を確認します;
- 端末のIDはページとブラウザコンソールに印刷されます。
- [トークンの削除]ボタンが表示され、既存のトークンを削除して再登録します。
- [ 送信 ]ボタンをクリックして送信できる通知パラメーターを含むフォームが表示されます。
- 自由裁量でパラメータを変更し、異なる通知を受け取ります。
HTTPリクエストを送信するには、任意のツールを使用して通知を送信できます。 cURLを使用できます。Chrome用のPostmanアプリの方が好きです。
要求は、前述のとおりです。
POST /fcm/send HTTP/1.1 Host: fcm.googleapis.com Authorization: key=AAAAaGQ_q2M:APA91bGCEOduj8HM6gP24w2LEnesqM2zkL_qx2PJUSBjjeGSdJhCrDoJf_WbT7wpQZrynHlESAoZ1VHX9Nro6W_tqpJ3Aw-A292SVe_4Ho7tJQCQxSezDCoJsnqXjoaouMYIwr34vZTs Content-Type: application/json { "data": { "title": "", "body": " 21:00", "icon": "https://eralash.ru.rsz.io/sites/all/themes/eralash_v5/logo.png?width=192&height=192", "click_action": "http://eralash.ru/" }, "to": "YOUR-TOKEN-ID" }
どこで
-
YOUR-TOKEN-ID
は、 アプリケーションページで受け取ったデバイスIDです。
以上です。 私たちは通知を受け取り、人生を楽しみます。
参照資料
- PUSHについて
- SSL
- UI
- JavaScript API
- 通知を送信する
- プレイする
2018-06-09に更新
いくつかの「機能」が通知の作業で見つかりました。
重複した通知
「重複した通知を修正する方法は?」という質問で何度か尋ねられました。
この問題は、複数のタブで同時に通知を送信するサイトを開くと明らかになります。 この場合、Service Workerは両方のタブに通知を送信し、 messaging.onMessageメソッドが両方のタブで起動します。 この問題は、私のデモプロジェクトで確認できます。
この問題を解決するには、 messaging.onMessage
メソッドで、通知がすでに別のタブに表示されていることを知る必要があります。 localStorage
を単一のストアとして使用localStorage
、通知量のハッシュによって通知を識別するか、一意のIDを割り当てることができます。 localStorage
ゴムでlocalStorage
なく、既に表示されている通知のIDはしばらくしてからクリーンアップする必要があることに注意してください。
これらの目的のためにpamelafox / lscacheライブラリをお勧めできます。
問題を解決する別の方法がある場合は、コメントを書いてください。
通知の写真
今日、 CTteroristのユーザーが私に目を向けました。彼は通知に画像が表示されていないことに気付きました。
少しテストして、私はそれを理解することができました。 image
フィールドは他の通知パラメーターとともにFirebaseに送信されますが、 image
フィールドはFirebaseから返されません。 問題は非常に簡単に解決されます。 data
フィールドでカードを送信し、通知表示ハンドラーでdata
から画像を抽出し、通知の所定の場所に挿入できます。
つまり、このフォームでメッセージを送信すると、Firebaseは画像を失います。
{ "notification": { "title": "Bubble Nebula", "body": "It's found today at 21:00", "icon": "https://peter-gribanov.github.io/serviceworker/Bubble-Nebula.jpg", "image": "https://peter-gribanov.github.io/serviceworker/Bubble-Nebula_big.jpg", "click_action": "https://www.nasa.gov/feature/goddard/2016/hubble-sees-a-star-inflating-a-giant-bubble" }, "to": "YOUR-TOKEN-ID" }
ただし、画像をdata
転送すると、画像が表示されdata
。
{ "data": { "title": "Bubble Nebula", "body": "It's found today at 21:00", "icon": "https://peter-gribanov.github.io/serviceworker/Bubble-Nebula.jpg", "image": "https://peter-gribanov.github.io/serviceworker/Bubble-Nebula_big.jpg", "click_action": "https://www.nasa.gov/feature/goddard/2016/hubble-sees-a-star-inflating-a-giant-bubble" }, "to": "YOUR-TOKEN-ID" }
通知表示ハンドラーは、上記の例と同じです。
messaging.onMessage(function(payload) { console.log('Message received. ', payload); // ServiceWorker navigator.serviceWorker.register('firebase-messaging-sw.js'); // Notification.requestPermission(function(result) { if (result === 'granted') { navigator.serviceWorker.ready.then(function(registration) { // TTL .. // data payload.data.data = JSON.parse(JSON.stringify(payload.data)); registration.showNotification(payload.data.title, payload.data); }).catch(function(error) { console.log('ServiceWorker registration failed', error); }); } }); });
同様に、Service Worker( firebase-messaging-sw.js
)
messaging.setBackgroundMessageHandler(function(payload) { console.log('Handling background message', payload); // TTL .. // data payload.data.data = JSON.parse(JSON.stringify(payload.data)); registration.showNotification(payload.data.title, payload.data); });