user icon

Firebase Cloud Messaging をブラウザで利用する

AndroidやiOSのアプリで、Push通知をするのによく使うFirebase Cloud Messagingですが、ブラウザでも使う事が出来るらしいので、試してみました。
こちらの記事を参考にしています。

大量の通知を試したい時に、AndroidやiOSアプリをインストールさせなくて済むので、検証の助けになるかも知れません(アプリの動作を試すのには向いていませんが)。

Webアプリの登録

Firebase Consoleでプロジェクトを選択、あるいは作成します。
ブラウザを使うのでアプリを追加の中から、ウェブを選択。
アプリ名を適当に入れて、アプリを登録を押します。
Firebase Hostingを使いたいなら、設定にチェックを入れて下さい。

Firebase SDKの追加

Firebase SDKの追加ですが、const firebaseConfig = {…}; の部分をコピーしておきます。
最下部の、コンソールに進む、で完了です。

鍵ペア作成(VAPID Key)

左上歯車アイコンの、プロジェクトの設定を選択します。
Cloud Messagingタブを選んで、下部のウェブの構成でGenerate Key Pairを押して、ここで表示される鍵ペアをコピーします。秘密鍵の方は不要です。
この時点で、ブラウザのTokenを取得する事が出来るようになりました。

Firebase Admin SDK

続いて、サービスアカウントタブを選択し、Firebase Admin SDKの秘密鍵を生成します。
上のFirebase SDKはTokenの取得に使いますが、このFirebase Admin SDKはPush通知に使います。
新しい秘密鍵を生成ボタンを押して、警告が出ますが生成を選択すると、jsonファイルがダウンロードされます。
と言っても秘密鍵の作成が目的なので、今回このファイルは使いません。

ブラウザからToken登録

httpsでアクセス可能な場所に、以下のhtmlを配置します。
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.2" />
<title>FCM Token登録</title>
<script type="module">
    // Import the functions you need from the SDKs you need
    import { initializeApp } from "https://www.gstatic.com/firebasejs/11.2.0/firebase-app.js";
    import { getAnalytics } from "https://www.gstatic.com/firebasejs/11.2.0/firebase-analytics.js";
    import { getMessaging, getToken } from "https://www.gstatic.com/firebasejs/11.2.0/firebase-messaging.js";
    // TODO: Add SDKs for Firebase products that you want to use
    // https://firebase.google.com/docs/web/setup#available-libraries

    // Your web app's Firebase configuration
    // For Firebase JS SDK v7.20.0 and later, measurementId is optional
    const firebaseConfig = {
        // Firebase SDKの追加で取得したfirebaseConfigで上書き
    };

    // Initialize Firebase
    const app = initializeApp(firebaseConfig);
    const analytics = getAnalytics(app);

    // 登録
    const btn = document.getElementById('regist');
    btn.onclick = function(){
        console.log("clicked");
        var el = document.getElementById("username");
        if (!("Notification" in window)) {
            // ブラウザーが通知に対応しているか調べる
            alert("このブラウザーはデスクトップ通知には対応していません。");
        }else if(el.value.length == 0){
            alert("ユーザー名を入力して下さい。");
        } else if (Notification.permission !== "denied") {
            Notification.requestPermission().then((permission) => {
                const vapidKey = "VAPID_PUBKEY"; // 鍵ペア作成(VAPID Key)で作成された値
                const messaging = getMessaging();
                try{
                    // Add the public key generated from the console here.
                    getToken(messaging, {vapidKey:vapidKey}).then((token) => {
                        console.log(token);
                        showToken(token);
                    });
                }catch(e){
                    console.error(e);
                }
            });
        } else {
            alert("Notification permission is denied.");
        }
    }

    function showToken(token){
        document.getElementById("box").style.display = "block";
        document.getElementById("result").innerHTML = token;
    }
</script>
</head>
<body>
<form method="POST" id="form">
    <button type="button" id="regist">Push通知登録</button>
</form>
<br>
<div id="box" style="display:none;">
    <div>Token: </div>
    <div id="result" style="border: solid 1px #CCCCCC; padding: 4px;"></div>
    <div>&nbsp;</div>
</div>
</body>
</html>
ブラウザでアクセスして、ボタンを押して、トークンが表示されたらOKです。
Tokenはコピーして次で使用します。

ブラウザの挙動について

※FirefoxはToken取得は出来ても、Push通知時にTHIRD_PARTY_AUTH_ERRORを起こす事が有るようです。
プロジェクトAでは全く発生せず、プロジェクトBでは必ず発生すると言う状況でした。
というかこの記事の検証用に追加したプロジェクトで起きて、調べまくりました。
一回目のプロジェクトでは問題なかったのに・・・。
https://stackoverflow.com/questions/72737181/how-do-i-fix-the-problem-behind-third-party-auth-error-when-using-googles-api
https://stackoverflow.com/questions/73218243/fcm-messages-not-being-sent-to-firefox
そんなわけで、こちらでは解決出来ないため、Chromeを使わせるしかない状況のようです。

Edgeはブラウザの設定でサイトの許可が必要でしたが、登録自体は可能でした。
iOSは制限が強く、簡単に使うためにブラウザを、と言う趣旨から外れるので除外しました。
結論Chrome(かEdge)使えになってしまうのは、仕方ないですね。

ブラウザ(OS)Token登録Push通知
Firefox (Windows)△(別プロジェクトで原因不明のエラー)
Google Chrome (Windows)
Edge (Windows)△(ブラウザのセキュリティ設定が必要)
Chrome(Android)

Push通知

DocumentRoot直下に/firebase-messaging-sw.jsを作成し、以下を記載します。
// Push通知を受け取ると呼ばれる
self.addEventListener('push', function (event) {
    // メッセージを表示する
    var data = {};
    if (event.data) {
      data = event.data.json();
    }
    var title = data.notification.title;
    var message = data.notification.body;
    event.waitUntil(
      self.registration.showNotification(title, {
        'body': message
      })
    );
});

Bearer Token(access_token)の簡単な取得方法

gcloudコマンドで出来ます。
このtokenの有効期間は(多分)1時間と短いので、数十分後にはまた生成する必要が有ります。
[project name]はFirebase Consoleで選択したプロジェクト名またはIDを指定します。
gcloud auth login
# ブラウザが開くのでGoogleアカウントを選択してログイン
gcloud config set [project name]
gcloud auth print-access-token

curlでPush通知

curl -X POST \
  -H "Authorization: Bearer [access_token]" \
  -H "Content-Type: application/json" \
  -d '{
    "message": {
      "token": "[browser_token]",
      "notification": {
        "title": "Push 通知のタイトル",
        "body": "Push 通知の本文"
      }
    }
  }' \
  "https://fcm.googleapis.com/v1/projects/[project_id]/messages:send"
[access_token]をgcloud auth print-access-tokenで出力された値に、
[browser_token]をブラウザで登録したTokenに、
[project_id]をFirebase のproject idに変更します。
project_idは、Firebase Consoleで、設定>全般タブのプロジェクト IDの値となります。
実行時ブラウザを起動していると、次のような通知が来ます。
Facebooktwitterlinkedintumblrmail
名前
E-mail
URL
コメント

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)