HAL_DATA_techBlog

HALDATAの技術ブログとリリース情報です。

Firebaseを使ってWebプッシュ通知を実装する

プッシュ通知とは、何らかのイベントをトリガーにサーバ側からユーザ側へメッセージを送信する仕組みのことです。
例えばニュースアプリでの号外や、チャットアプリでのメッセージ受信が代表的です。
こういったケースは大部分がネイティブアプリによって実現されてきました。

Webプッシュ通知とは、文字通りプッシュ通知をネイティブアプリではなくWebのみで実現する仕組みのことです。

プッシュ通知の仕組み

プッシュ通知はサーバアプリケーションからユーザのデバイスへメッセージを送信する仕組みですが、実はサーバアプリケーション⇔ユーザデバイス間が直接メッセージをやり取りするわけではありません。
サーバサイドとユーザデバイス第3者的が仲介し、メッセージを伝達することで実現します。

![Webプッシュ通知の概要](https://cz-cdn.shoeisha.jp/static/images/article/11278/11278_001.png(

このような仕組みはPublish/SubscribeあるいはPub/Sub(パブサブ)とも呼ばれます。
プッシュ通知送信サービスとして最も代表的なのは、AppleAPNs(Apple Push Notification service)とGoogleFCM(Firebase Cloud Messaging)です。

f:id:skokado:20190909234146p:plain

本記事では、無料でWebプッシュ通知の導入ができるFCMを用いた解説をします。

Firebase consoleの操作

プロジェクトの作成

まずFirebase consoleにアクセスしてプロジェクトを追加します。プロジェクトは複数のアプリケーションを管理するための箱のようなものなので、名前は何でも良いでしょう。

アプリケーションを登録する

プロジェクトにアプリを追加します。
iOSAndroid、Webの3種類があるのでWebを選択します。

f:id:skokado:20190909230931p:plain

f:id:skokado:20190909230945p:plain

各種キーなどの設定

プッシュ通知送信のために必要な以下の項目を生成、取得します。

  • 構成オブジェクト: Firebase との連携における初期化処理に必要な情報
  • サーバーキー: プッシュ通知送信時の認証の役割を果たすもの(※公開せず、サーバサイドの処理で利用するもの)
  • 送信者ID: アプリケーション事業者を識別するもの
  • ウェブプッシュ証明書: いわゆる VAPIDキー にあたるもの。公開鍵をコード内に記述する(※秘密鍵は公開しない)。
    ※参考 - VAPID の仕組み

「プロジェクトの設定」を選択して設定画面に進みます。

f:id:skokado:20190909231037p:plain

構成オブジェクト

[全般]タブ] > [マイアプリ] > [Firebase SDK snippet]

f:id:skokado:20190909231425p:plain

サーバーキー

[クラウドメッセージング]タブ >[サーバーキー]

f:id:skokado:20190909231613p:plain

送信者ID

f:id:skokado:20190909231747p:plain

ウェブプッシュ証明書

[クラウドメッセージング]タブ > [ウェブプッシュ証明書]

f:id:skokado:20190909231955p:plain

プッシュ通知の実装

ここまでで必要な設定値やキーが取得できました。
以上を踏まえてコードを見ていきましょう。

Firebase SDKの読み込みと初期化

まず、ユーザデバイスにFirebase SDKを読み込ませます。プッシュ通知の送信に必要な「デバイス登録トークン」を生成/登録するためです。
htmlファイルのbodyタグ内に記載します。

<script src="https://www.gstatic.com/firebasejs/5.10.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.10.1/firebase-messaging.js"></script>

1行目のfirebase-app.jsはFirebaseを利用する際の全てのサービスで必要なものです。
それに加えて今回はFCMを使うため、2行目のSDKを指定しています。

続いて、構成オブジェクトを使用してFirebaseの初期化を行います(これはユーザデバイスで実行されるものです)。
構成オブジェクトの後にfirebase.initializeApp(firebaseConfig);でユーザはFirebase SDKの処理を実行することができるようになります。

<script>
  const firebaseConfig = {
    apiKey: "[ウェブ API キー]",
    authDomain: "[プロジェクト名].firebaseapp.com",
    databaseURL: "https://[プロジェクト名].firebaseio.com",
    projectId: "[プロジェクト名]",
    storageBucket: "",
    messagingSenderId: "[送信者ID]",
    appId: "1:[送信者ID]:web:68305****"
  };
  firebase.initializeApp(firebaseConfig);
</script>

FCM用のサービスワーカー: firebase-messaging-sw.js

Firebase がプッシュ通知を送信するために必要です。
PWAの記事でも解説しましたが、サービスワーカーとは ユーザに代わってバックグラウンドでのやり取りを実現するものです。

これはファイル名がfirebase-messaging-sw.jsで固定であり、必ず最上位階層に配置します。
このスクリプトmessagingSenderIdに上記で取得した「送信者ID」の値を記述します。

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

firebase.initializeApp({
    'messagingSenderId': '[送信者ID]'
});

const messaging = firebase.messaging();

messaging.setBackgroundMessageHandler(function (payload) {
    const notificationTitle = payload.notification.title;
    const notificationOptions = {
        body: payload.notification.body,
        icon: payload.notification.icon
    };
    return self.registration.showNotification(notificationTitle, notificationOptions);
});

登録トークンの発行

最後に、登録トークンを発行してユーザデバイスにプッシュ通知を送信できるようにします。
登録トークンとは、ユーザデバイス1つ1つを特定し識別するための文字列です。
登録トークンの発行はユーザデバイスからの要求を契機にFirebaseが行います

Firebaseから返された登録トークンをサーバアプリケーションが取得できるよう実装する必要があります。
本記事では、Cookieとしてブラウザに保存するものとします。

トークン発行の処理のためにget-token.jsファイル作成します。
ここまでで記載したFirebase SDK初期化などが完了していないといけないため、deferオプションを付けて最下部に記載した方が良いでしょう。

<script defer src="js/get-token.js"></script>

そして、肝心のget-token.jsは以下のようになります。

  • js/get-token.js
// メッセージング オブジェクトの取得
const messaging = firebase.messaging();

// アプリにウェブ認証情報を設定する
messaging.usePublicVapidKey("BLTmXNdceHRE_mFNnZ6Tr63eO9XslaV9QyuBZMY1A-S_JRFb9j6B4SZfe3t0XF_te0zDpC1JUVigaZ0i4Xwenrs");

// 初期化
window.onload = function () {
    // 権限要求
    messaging.requestPermission().then(function () {
        // 登録トークンの取得
        messaging.getToken().then(function (token) {
            document.cookie = 'registrationToken=' + token;
        }).catch(function (err) {
            console.log(err);
        });
    }).catch(function (err) {
        console.log('Could not get permission.');
    });
};

messaging.requestPermission()でユーザへ通知送信の許可を訪ねます。

f:id:skokado:20190909235055p:plain

そして、ユーザが通知送信を許可するとtoken変数に格納された登録トークンをCookieとして保存します。
CookieのKey名はregistrationTokenとしています。

動作確認

それではアクセスして確認してみましょう。
サイトへアクセスして通知を求めるダイアログが表示されたら「許可」を押します。

f:id:skokado:20190909235526p:plain

その後Cookieが発行され、長い文字列が保存されればOKです。

f:id:skokado:20190909235735p:plain

この値を保存します。
いよいよプッシュ通知を送信します。

プッシュ通知の送信するにはFirebaseのサーバへHTTP POSTメッセージを送信します。
その際、送信者の認証のために「サーバーキー」をヘッダに付与します。
curlコマンドで送信するなら以下のようになります。
※コマンドを実行する際、ブラウザのページは閉じる他ページを表示している状態にしておいてください。

curl "https://fcm.googleapis.com/fcm/send" \
    -X POST \
    -H "Content-Type: application/json" \
    -H "Authorization: key=[サーバーキー]" \
    -d '{
        "notification": {
        "title": "Hello World!",
        "body": "by HAL Data!",
        "icon": "https://images-na.ssl-images-amazon.com/images/I/51lVPTHuDkL._SX342_.jpg",
        "click_action": "https://www.haldata.net/"
    },
    "to": "[登録トークン]"
    }'

コマンドを送信すると・・・

f:id:skokado:20190910000623p:plain

来ました!!

まとめ

プッシュ通知の仕組みとWebアプリケーションのプッシュ通知送信の流れを解説しました。
プッシュ通知といえばネイティブアプリケーションのイメージですが、Webでも簡単に導入することができます。

手軽に導入、送信できる分ユーザへのアプローチが過剰になってしまうとユーザに通知を拒否されてしまって逆効果になるリスクもあります。
バランスを考え効果的なマーケティングに繋がるように活用したいですね。

以上