エンジニアの卵の成長日記

ふわっちで配信してますhttps://whowatch.tv/profile/w:kurowasi2525

Nuxt.js+Firebase Cloud Messaging(FCM)を使ったPWA化が簡単で衝撃的だった

※この記事は,3時間書けて作成していたが,ミスで保存できていなかったので,一から作り直したため,
やる気がなくなり雑になっています.


概要

Nuxt.jsで作ったシステムをPWA化させた.

PWA化を実装してみて,PWAの素晴らしさ・Nuxt.jsの素晴らしさが更にわかったので伝えたい!

そして,Nuxt.js+Firebase Clouds Messaging(以下,FCM)に関する記事が少なかったため,実装方法を書いていく.


背景

上記で説明したVIROというシステムは,友達に既に使って貰っている.

そこで出てきた文句として,

  • 毎回ログインすることが面倒
  • ブラウザの上下が邪魔(URLを入力する部分,戻るボタンや他のタブを表示するボタン)
  • プッシュ通知が欲しい

などなど...

スマホアプリのような機能が欲しいというのが基本的だった.

どう対応するか悩んでいたところ,小学校の同級生がPWAについて推していたことを思い出した.

調べてみると簡単に実装できそうだったので,PWA化した.


PWAとは?

Progressive Web Appsの略称で,WebサイトでスマホアプリのようなUXを実現させるというもの.

Web Applicationのその先という感じですかね.

PWAの代表的な例としては,

  • オフライン対応
  • ホーム画面に追加
  • プッシュ通知

などがある.


PWAの利点は?

自分が実装してみての利点は,WebAppを作成するだけで,ある程度アプリ層までも作れるということ.

Web技術でネイティブアプリのようなものを作る技術は前からあったと思う.(Monacaなど)

でも,学習コスト・実装コストは高く,SwiftやKotlinを勉強した方がよくねって思ってしまう.

しかし,PWA化は学習コスト・実装コストが低いためおすすめである.

そして,使ってもらう側の一番の利点は,ダウンロード不要ということが一番だと思う.


※PWAの利点や詳しい内容は以下のサイト見てください.
qiita.com


Nuxt.jsとは?

Vue.jsの環境をいい感じにやってくれて,SSRが簡単にできる.

この記事を見ている方は,Nuxt.jsに詳しい方ばかりだと思うので省略.


オフライン対応・ホーム画面に追加

Nuxt.jsの場合,

PWAモジュールの追加

画像の追加

設定ファイルの修正

を行うだけで,PWA化ができる(あら簡単)

Introduction · Nuxt PWA Module

詳しい実装方法は,素晴らしい記事がたくさんあるので,以下のサイトを見てください.

speakerdeck.com

techblog.scouter.co.jp

www.sho-yamane.me


DBに関しては,Firebase Realtime Databaseを利用していたため,既にオフライン対応している.


プッシュ通知対応

プッシュ通知に関しては,Nuxt.jsがOneSignal用のモジュールがあるため,上記の記事を見てもらうとわかる通り,

OneSignalを使うのが一般的みたい.

Onesignal Module · Nuxt PWA Module

今回は,Firebase Realtime Databaseを利用していることやOneSignalは色々と面倒だったので,Firebase Cloud Messagingを利用することにした.


youtu.be


FCMは,

設定ファイルを書き,

10行ほど書けば,プッシュ通知を受け取る状態にできる.

後は,サーバ側からでもフロント側からでも内容を送信すれば通知が表示されるようになる.

Firebaseの公式から,実装方法の動画があるため,お兄さんの言う通りに書いていけば実装できる.

youtu.be


Firebaseへのプロジェクトの追加は,この記事では省く.

メッセージを受信するようにブラウザを設定する

manifest.jsonにハードコード値を指定するのだが,Nuxt.jsではnuxt.config.jsに記述する.

manifest: {
    "gcm_sender_id": "103953800507"
}

この値は固定なので,どんな人でもこの値になる.

上記の記事で,既にPWAを実装している場合,nameやtitle,lang,theme_colorなどのプロパティが記述されているはず.


Service Workerの設定

Nuxt.jsの場合,staticディレクトリにfirebase-messaging-sw.jsを作成する.

FCMでは,Service Workerのファイル名が決まっているみたい.(Service Workerをちゃんと理解できてない)

まず始めに,コンソールから送信者IDを取得する.

コンソール→プロジェクトの設定→クラウドメッセージングタブ

f:id:kurowasi2525:20180313023029p:plain

f:id:kurowasi2525:20180313023032j:plain

firebase-messaging-sw.js

importScripts('https://www.gstatic.com/firebasejs/4.0.0/firebase-app.js')
importScripts('https://www.gstatic.com/firebasejs/4.0.0/firebase-messaging.js')

const config = {
    apiKey: "",
    messagingSenderId: "コンソールから取得した送信者ID"
}

if (!firebase.apps.length) {
    const firebaseApp = firebase.initializeApp(config)
}

const messaging = firebase.messaging()


プッシュ通知の受信を実装

今回は,トップ画面で利用しているコンポーネントやpagesで実装した.

僕はcreated()内に実装.

const messaging = firebase.messaging()
messaging.requestPermission()
    .then(() => {
        console.log('Have permission')
        return messaging.getToken() //ユーザにプッシュ通知を表示する権限の許可を表示
    ]).then((currentToken) => {
        if (currentToken) {
            // プッシュ通知を受信し,表示できる状態
        }
    }).catch((err) => {
        console.log('Error Occurred.')
    })


これで実装完了.

後は通知を送るのみ.


プッシュ通知の送信

今回は,Firebaseのみで完結させたかったため,フロント側でデータベースのお知らせ情報が追加された場合,

自分に向けてプッシュ通知を送るという実装にした.

import firebase from 'firebase'

export default {
    created () {
        firebase.database().ref('notifications/' + uid).on('value', (snapshot) => { //この部分はFirebase Realtime Database部分
                const messaging = firebase.messaging()
                messaging.requestPermission()
                    .then(() => {
                        console.log('Have permission')
                        return messaging.getToken() //ユーザにプッシュ通知を表示する権限の許可を表示
                    }).then((currentToken) => {
                        if (currentToken) {
                            // この部分までは上記で実装しました.
                            // この部分はデータベースのお知らせ情報が追加などの修正がおきると呼ばれる
                            // 今回はこの部分に送信部分を記述していく
                        }
                    }).catch((err) => {
                        console.log('Error Occurred.')
                    })
        }
    }
}

プッシュ通知を送る場合,

プッシュ通知を送るためのURLに

受信者のトークンID

通知内容

送信者のサーバーキー(送信者IDの場所と同じ.コンソール→プロジェクトの設定→クラウドメッセージングタブ)

をPOST送信することで送信される.

if (currentToken) {
    let argObj = { // 受信者のトークンIDと通知内容
        to: currentToken,
        notification: {
            body: 'メッセージ内容'
            title: 'タイトル',
            click_action: 'クリックした際に開くURL',
            icon: 'アイコン'
        }
    }
    let optionObj = { //送信者のサーバーキー
        headers: {
            'Content-Type': 'application/json',
            'Authorization': 'サーバーキー'
        }
    }
    axis.post('https://fcm.googleapis.com/fcm/send', argObj, optionObj)
}


これで送信部分も実装できたと思う.


所感

今回の実装を通して,

Nuxt.jsやべー!

Firebaseすげー!

PWA最高!!!

ってなりました笑

オフライン対応やホーム画面に追加などは,Nuxt.jsの場合数分で実装できます.

本当にやらなきゃ損ってレベル.

Android端末を持っていないため,実装した時はさほど感動がなかったのですが,

友達のAndroid端末で利用した際に驚きを隠せませんでした.

ホーム画面に追加をすると,ホーム画面に追加されるわけではなく,

Androidアプリをダウンロードすると表示される,アプリ一覧の部分に追加されます.

アプリを消す際もアンインストールと表示され,起動時にはスプラッシュ画面が表示されます.

しかも全画面で表示されるので,見た感じは普通のアプリと変わらず,僕はWebAppだけじゃなく,アプリも作ったんだという錯覚と謎の感動・達成感がありました笑

Firebaseも数行で色々できて本当にすごいです.

通知が来た時の感動はやばかった...


結論

PWAに未来を感じた


※小言
あー

iOS11.3まだかなー

Android端末欲しいなー