34
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

PWAAdvent Calendar 2018

Day 5

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

Last updated at Posted at 2018-08-17

#はじめに
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

34
27
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?