Push通知
vue.js
ServiceWorker
PWA
vue-cli
PWADay 5

vue.js&PWAにwebプッシュ通知を適用させてみた


はじめに

firebase&PWAでのpush通知のサンプルはよく見かけたのですが、

vue-cliで作ったプロジェクトにpush通知を適用するサンプルはなかなか見つからなかったので試行錯誤してみました。

webpackの知識が浅いので、もっと良いやり方あるで!って人はぜひ教えてください。

pushサーバーを作るのは大変そうなので、今回はfirebaseを利用しました。

なお、この記事ではpush通知やらfirebaseやらの細かい仕様は解説しません。


必要なもの

vue-cli(node,npmなども)

firebaseのアカウント


ひな形プロジェクト作成

こちらの記事を参考に作成しました。

最近vue-cli 3がリリースされましたが、今回は2系で作成しました。

なおリンク先では 3.Vue.jsのSPAをPWA化する という手順を踏んでいますが、今回はやりません。

出来上がったプロジェクトをnpm run buildすると、distフォルダの中にservice-worker.jsが出来上がっているのが分かります。

このservice-worker.jsにwebpush通知の記述をすればpush通知が動くはずなのですが、

デフォルトだとpush通知の記載がないのでどうにかしてpush通知のコードをこのjsファイルに追記しなければなりません。

build結果のjsに対して直接記述するのはアレなので、設定ファイルを多少いじって工夫します。


push通知の記述をbuild結果のserviceworkerにマージする


自前のサービスワーカーを用意

src内のstaticフォルダ内にjsファイルを追加します。

ファイル名はなんでもいいのですが、今回はmysw.jsとします。


mysw.js

self.addEventListener("push", function(event) {

event.waitUntil(
self.registration.pushManager.getSubscription()
.then(function(subscription) {
if (subscription) {
return subscription.endpoint
}
throw new Error('User not subscribed')
})
.then(function(res) {

return self.registration.showNotification('title', {
body: 'contents'
})
})
)
})


self.registration.showNotificationの引数はアイコン、タグなど色々ありますが今回は省略します。


設定ファイルをいじる

ここでいじるのはwebpack.prod.conf.jsです。

SWPrecacheWebpackPluginの部分の記載を下記のように修正します。


webpack.prod.conf.js

// service worker caching

new SWPrecacheWebpackPlugin({
cacheId: 'your-project',
filename: 'service-worker.js',
staticFileGlobs: ['dist/**/*.{js,html,css}'],
minify: true,
stripPrefix: 'dist/',
importScripts: ['./static/mysw.js']//この行を追加
})

これによって、デフォルトで出来上がるservice-worker.jsに、自分が書いたmysw.jsがマージされます。

どうなっているか気になる方は、再度npm run buildした後のservice-worker.jsファイルの中を確認してみてください。

ここまでで半分くらいです。続いてはfirebaseと連携する処理を記述していきます。


firebaseと連携


firebaseのプロジェクト作成

とりあえずfirebaseであたらしいprojectを作ってみましょう。

firebaseにログインして新しいプロジェクトを追加しましょう。

プロジェクトを追加したら、プロジェクトの設定>クラウド メッセージングタブ内の、

・サーバーキー

・送信者ID

をメモってください。

ここで作成したプロジェクトがpushサーバーの役割を担います。


ソースコード修正

manifest.json,service-worker-prod.jsを修正します。


manifest.json

"gcm_sender_id":"送信者ID"//ファイルの最後に←のコードを追加(先ほどメモった送信者IDをここに書く)


service-worker-prod.jsについてはwindow.addEventListener('load', function()以下を下記の通り修正


service-worker-prod.js

    window.addEventListener('load', function() {

if ('serviceWorker' in navigator) {
navigator.serviceWorker.register("service-worker.js");
navigator.serviceWorker.ready.then(function(registration) {
return registration.pushManager.getSubscription().then(function(subscription) {
if (subscription) {
return subscription;
}
return registration.pushManager.subscribe({
userVisibleOnly: true
})
})
}).then(function(subscription) {
console.log("pushManager endpoint:", subscription.endpoint)
}).catch(function(error) {
console.warn("serviceWorker error:", error)
})
}
});

push通知を許可するようにソースを修正しています。

また、subscriptionのendpointをconsole.log出力している処理がありますが、

最後のpush通知に重要な情報を吐き出しています。

ここまでやったらpush通知の準備完了です。


push通知を試してみる


資源をhttps対応のサーバーに配置

私はお手軽なgithubPagesを利用しています。

npm run buildで吐き出されるdist配下の資源をまるっとgithubにpushしてgithubPagesの設定をしてください。

あまり自分はFirebase詳しくないのですが、firebaseは静的資源のホスティングサービスあるみたいなので、そっちでもいいかもです。


ページにアクセス

ディベロッパーツールを開きながら、該当ページにアクセスしてください。

うまくいっていたらコンソールログに

pushManager endpoint: https://android.googleapis.com/gcm/send/*endpointの値*

が出力されているはずです。

このendpointの値は最後のpush通知に必要な値なのでメモってください。


curlコマンドでpush通知

下記コマンドを叩くとwebにpush通知が届くはずです。

curl "https://fcm.googleapis.com/fcm/send" \

-X POST \
-H "Content-Type: application/json" \
-H "Authorization: key=サーバーキー" \
-d '{
"notification": {
"title": "タイトル",
"body": "本文",
"click_action": "http://example.com"
},
"to": "endpointの値"
}'

今回は簡単のためにcurlコマンドを利用していますが、rest系のクライアントツール、Ajaxでも同様に動きます。


参考URL

https://qiita.com/gyarasu/items/2f18edc4ae251180d89e

https://qiita.com/keki/items/81634135586763de235a

https://qiita.com/srai0628/items/ebd417b7877295031718