aikawa

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

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

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

※試すには、https接続可能なサーバが必要になります(localhostでも可能なようですが、大量の通知を試すには、誰からでもアクセス出来た方が良いと思うので)。

Webアプリの登録

Firebase Consoleでプロジェクトを選択、あるいは作成します。
ブラウザを使うのでアプリを追加の中から、ウェブを選択。



アプリ名を適当に入れて、アプリを登録を押します。
Firebase Hostingを使いたいなら、設定にチェックを入れて下さい。

Firebase SDKの追加

Firebase SDKの追加ですが、const firebaseConfig = {…}; の部分をコピーしておきます。

このfirebaseConfigの部分は、次のVAPID Keyと一緒に、ブラウザのToken登録画面で使用します。
コピーし忘れたら、設定>全般タブ>マイアプリ>ウェブアプリ>[アプリ名]からコピーできます。

最下部の、コンソールに進む、で完了です。

鍵ペア作成(VAPID Key)

左上歯車アイコンの、プロジェクトの設定を選択します。

Cloud Messagingタブを選んで、下部のウェブの構成でGenerate Key Pairを押して、ここで表示される鍵ペアをコピーします。秘密鍵の方は不要です。

これも、ブラウザのToken登録画面で使用します。

この時点で、ブラウザのTokenを取得する事が出来るようになりました。

Firebase Admin SDK

続いて、サービスアカウントタブを選択し、Firebase Admin SDKの秘密鍵を生成します。

上のFirebase SDKはTokenの取得に使いますが、このFirebase Admin SDKはPush通知に使います。

新しい秘密鍵を生成ボタンを押して、警告が出ますが生成を選択すると、jsonファイルがダウンロードされます。

と言っても秘密鍵の作成が目的なので、今回このファイルは使いません。

ブラウザからToken登録

httpsでアクセス可能な場所に、以下のhtmlを配置します。

※firebaseConfigとVAPID_PUBKEYを、
Firebase SDKの追加で取得したfirebaseConfig、
鍵ペア作成(VAPID Key)で作成された値
に入れ替えて下さい。

<!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> </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の値となります。

実行時ブラウザを起動していると、次のような通知が来ます。