状況
このサイトの「Push Notification編」を参考に
PWAでのプッシュ送信についてひと通りやりました。それに関しては問題なかったのですが
少し変えたいと変更を加えたときに、通知承認のデータを変数に受け取るという
問題が解決できず悩んでいます。
PWAとかNodeとかの以前の問題で、表題とほとんど関連性がないと思いますが・・・
プロジェクト概要
このプロジェクトの概要は、サイトのサービスワーカーに(service-worker.js)、
'push'イベントが発生すると既定の通知内容を表示するハンドラを設定しており、
main.jsではユーザがページにアクセスした際に、通知の承諾をすると
そのEndpoint、Author、Keyをページに表示します。
別途、push.jsというファイルにそれら表示情報を埋め込んで(npmの'web-push'を使ってます)
Nodeで実行しプッシュ通知の送信をするというものです
やろうとしていること
現状ではpush.jsの実行後に通知が表示されますが、これを、ユーザが承諾した時点でプッシュ通知を表示したいと思い、main.js内の、承諾時のデータを画面表示する処理の後にpush.jsの処理を追加しようとしました
main.js(変更前)
js
1if ('serviceWorker' in navigator) { 2 document.addEventListener('DOMContentLoaded', () => { 3 let endpoint = document.querySelector('#subscription-endpoint'); 4 let key = document.querySelector('#subscription-public-key'); 5 let auth = document.querySelector('#subscription-auth'); 6 7 navigator.serviceWorker.register('./service-worker.js'); 8 navigator.serviceWorker.ready 9 .then((registration) => { 10 return registration.pushManager.subscribe({userVisibleOnly: true}); 11 }) 12 .then((subscription) => { 13 var rawKey = subscription.getKey ? subscription.getKey('p256dh') : ''; 14 key.value = rawKey ? btoa(String.fromCharCode.apply(null, new Uint8Array(rawKey))) : ''; 15 var rawAuthSecret = subscription.getKey ? subscription.getKey('auth') : ''; 16 auth.value = rawAuthSecret ? btoa(String.fromCharCode.apply(null, new Uint8Array(rawAuthSecret))) : ''; 17 endpoint.value = subscription.endpoint; 18 console.log(`GCM EndPoint is: ${subscription.endpoint}`); 19 }) 20 .catch(console.error.bind(console)); 21 }, false); 22}
push.js(変更前)
js
1'use strict'; 2let push = require('web-push'); 3const GCM_API_KEY = '略'; 4push.setGCMAPIKey(GCM_API_KEY); 5const data = { 6 'endpoint': '略', 7 'userAuth': '略', 8 'userPublicKey': '略' 9}; 10 11push.sendNotification(data.endpoint, { 12 payload: 'service worker プッシュテスト', 13 userAuth: data.userAuth, 14 userPublicKey: data.userPublicKey, 15}) 16.then((result) => { 17 console.log(result); 18}) 19.catch((err) => { 20 console.error('fail', err); 21}); 22
このmain.js内にpush.jsの内容を埋め込んでみたものが以下です。
画面表示に使っているデータを'web-push'に渡すオブジェクト”data”にセットしているだけです。
これをトランスパイルしてbundle.jsとし、main.jsのかわりにindex.htmlから呼びます
するとコンソールに後述のような'web-push'のエラーが出てしまいます。
ページにはAuth,Key,Endpointが表示されてはいますが。
App.js(main.jsにpush.jsを埋め込んだファイル)
js
1 2'use strict'; 3 4let push = require('web-push'); 5const GCM_API_KEY = '略'; 6push.setGCMAPIKey(GCM_API_KEY); 7let data = { 8 'endpoint': '', 9 'userAuth': '', 10 'userPublicKey': '' 11}; 12 13if ('serviceWorker' in navigator) { 14 document.addEventListener('DOMContentLoaded', () => { 15 let endpoint = document.querySelector('#subscription-endpoint'); 16 let key = document.querySelector('#subscription-public-key'); 17 let auth = document.querySelector('#subscription-auth'); 18 19 navigator.serviceWorker.register('./service-worker.js'); 20 navigator.serviceWorker.ready 21 .then((registration) => { 22 return registration.pushManager.subscribe({userVisibleOnly: true}); 23 }) 24 .then((subscription) => { 25 var rawKey = subscription.getKey ? subscription.getKey('p256dh') : ''; 26 key.value = rawKey ? btoa(String.fromCharCode.apply(null, new Uint8Array(rawKey))) : ''; 27 var rawAuthSecret = subscription.getKey ? subscription.getKey('auth') : ''; 28 auth.value = rawAuthSecret ? btoa(String.fromCharCode.apply(null, new Uint8Array(rawAuthSecret))) : ''; 29 endpoint.value = subscription.endpoint; 30 data.endpoint = endpoint.value; 31 data.userAuth = auth.value; 32 data.userPublicKey = key.value; 33 }).then(() => { 34 push.sendNotification(data.endpoint, { 35 payload: 'service worker プッシュテスト', 36 userAuth: data.userAuth, 37 userPublicKey: data.userPublicKey, 38 }) 39 .then((result) => { 40 console.log(result); 41 }) 42 .catch((err) => { 43 console.error('fail', err); 44 }) 45 }).catch(console.error.bind(console)); 46 }, false); 47} 48
エラー内容
error
1fail Error: "You must pass in a subscription with at least an endpoint." 2 generateRequestDetails web-push-lib.js:89 sendNotification web-push-lib.js:289 [195]</</< App.js:36 3App.js:45:16 4 [195]</</</< App.js:45
少なくともエンドポイントは渡せという意味のエラーだと思うのですが、
なぜ渡せてないのかわからず悩んでいます。
もともとは画面表示しているデータをそのままコピペして実行するpush.jsなので
どうしてこれでまずいのかがわからす悩んでいます。
処理の流れが理解できていない気がします。
オブジェクト”data”の各プロパティーに値がセットされる前に、
そのプロパティーのチェック処理が走っているような感じなのですが
また、あわせて教えていただきたいのですが、後日のプッシュ通知にも使うために
このようにユーザから得た承認のトークンなどの管理は
一般的にはどうしているのでしょうか?
どんどんDataBaseなどに保存していっているのでしょうか?
逆にブラウザの通知設定で削除されたりして承認を得られなくなったら、
その保有していた承認のデータは削除するとかでアップデートし管理しているのでしょうか?
あなたの回答
tips
プレビュー