やりたいことの概要
- Linux(Ubuntu)のBashスクリプト内で条件を満たした際にAndroidへプッシュ通知したい
- 通知の本文は適宜変更したい
- 個人のローカルPCから発信したい
この記事を書いた経緯
- メール送信の方が手軽で情報も多いが、他のメールに埋もれたり削除するのが面倒
- 2024年7月22日にAPIの変更があり新しい方法での紹介が少なかった
- Node.jsに初めて触れてバージョン違いに苦戦したため
APIの移行方法については公式webページに記載があるが、トークンの取得など色々と変更があり、FCMについて全く知らない状況からでは読み替えが難しかった。
環境
- 送信元: Ubuntu 20.04.06 LTS (WSL2上)
- 送信先: Google Chrome 133 (SH-M19, Android13)
- nvm 0.39.7
- npm 9.9.4
- node v18.20.6
参考にした公式のサンプルコード
- Chromeで端末のトークンを取得するのに利用
https://github.com/firebase/quickstart-js - Bashからwebプッシュを送信するのに利用
https://github.com/firebase/quickstart-nodejs
全体の流れ
- サンプルコードのダウンロード
- Node.jsのインストール(つまづきポイント)
- Firebaseの初期設定
- 端末のトークン取得
- 通知を送信する準備
- 通知の送信
サンプルコードのダウンロード
端末のトークンを取得する公式サンプルプログラムのダウンロード
git clone https://github.com/firebase/quickstart-js.git
通知を送信する公式サンプルプログラムのダウンロード
git clone https://github.com/firebase/quickstart-nodejs.git
Node.jsのインストール
ここが一番のつまずきポイント。
サンプルプログラムが指定するバージョンを入れないとうまく動かない。
2025年3月8日現在のコードではnpmは9.X.X、nodeは18.0.0以上20.0.0以下にする必要がある。
Node.js公式サイトのダウンロードページから自身の環境に合ったコマンドを取得する。
Node.js v18.20.7はnpm 10.8.2がインストールされてしまうので注意。
npmのダウングレードが面倒な方は素直にv18.20.6以下をインストールするのが良い。
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
nvm install 18.20.6
nvm alias default 18.20.6
ターミナルを開き直すかsource ~/.bashrc
をしてからインストールされたバージョンを確認。
npm -v # npmのバージョンが表示される。
node -v # Node.jsのバージョンが表示される。
Node.jsのバージョン指定方法
nvm install
の際にマイナーバージョンを指定すればインストールされるnodeのバージョンを細かく指定できる。
nvm install 18.19.1
メジャーバージョンのみ指定した場合、その時点での最新のマイナーバージョンが自動的に選ばれる。
nvm install 18 # 2025年3月8日現在ではv18.20.7がインストールされる
nvm ls-remote
要求されるバージョンの確認方法
quickstart-js内のpackage.jsonファイルに以下の記述があるため、npmは9.0.0以上10.0.0未満、nodeは18.0.0以上20.0.0以下にしないといけないことがわかる。
"engines": {
"npm": ">=9.0.0 <10.0.0",
"node": ">=18.0.0 <=20.0.0"
},
quickstart-nodejsに関してはpackage.jsonファイル内にenginesの項目はないのでバージョンの指定はされていない。
但し最新版のNode.jsで動く保証がないのは過去のコードを利用する際によくあることである。
依存パッケージに関してはquickstart-nodejs/messaging/package.jsonに以下の記述があるため、npm install
時にgoogle-auth-libraryは8.8.0、googleapisは118.0.0と互換性のあるバージョンがインストールされる。
"dependencies": {
"google-auth-library": "^8.8.0",
"googleapis": "^118.0.0"
}
Firebaseの初期設定
Firebaseプロジェクトの作成
この辺の作業はググればたくさん出てくる。
quickstart-js/messaging/README.mdの1~3を参考に以下の作業を行う。
- GoogleアカウントでFirebase consoleにログイン
- プロジェクトを追加
- 作成したプロジェクトにアプリを追加
- [プロジェクト設定]→[Cloud messaging]タブを選び、[ウェブプッシュ証明書]欄の"Generate key pair"ボタンを押す
サンプルファイルの編集
quickstart-js/messaging/README.mdの4を参考に、quickstart-js/messaging/config.tsにapiKeyやprojectIdをコピーする。
<YOUR_PUBLIC_VAPID_KEY_HERE>の部分は先ほど作ったウェブプッシュ証明書の鍵ペアとして表示されている文字列。
アプリ追加時の画面を閉じてしまった人は
- Firebase consoleで作成したプロジェクトを選択
- 左のアイコン群から[歯車アイコン]→[プロジェクトの設定]を開く
- [マイアプリ]欄の[次に Firebase を初期化し、使用するプロダクトの SDK の利用を開始します。]の下に必要な情報が表示される
Firebase CLIのインストールと設定
quickstart-js/messaging/README.mdの5,6を参考に、quickstart-js/messagingディレクトリにて以下を実行する。
# Firebase CLIのインストール
npm install -g firebase-tools
# Firebaseへログイン
firebase login
# Firebaseプロジェクトの指定
firebase use --add
依存パッケージのインストールとデプロイ
quickstart-js/messaging/README.mdのRunning the app using the Firebase CLI下の1,2およびTo deploy the sample app to production下の項目を参考に以下の作業を行う。
# 依存パッケージのインストール
npm install
# ビルド
npm run build
# デプロイ
firebase deploy
端末のトークン取得
Webページ(https://<project_id>.firebaseapp.com)にアクセスして[REQUEST PERMISSION]ボタンを押すと、トークンが文字列として表示されるのでメモする。
一度トークンを取得すれば次回以降はwebページへアクセスするだけでトークン文字列が表示される。
AndroidやWindowsではこの手順で問題ないが、iOSの場合はサイトをホーム画面に追加しないと通知が受け取れない。
Safariの場合はappleのサポートページを参考にホーム画面へ追加し、追加したアイコンを開いて[REQUEST PERMISSION]ボタンを押す。
Chromeについても同じ[四角に上矢印ボタン]からホーム画面へ追加できる。
通知を送信する準備
プロジェクトにサービスアカウントの追加
quickstart-nodejs/messaging/README.mdを参考にサービスアカウントを追加する。
- Firebase consoleで作成したプロジェクトを選択
- 左のアイコン群から[歯車アイコン]→[プロジェクトの設定]を開く
- [サービスアカウント]のタブを選ぶ
- [新しい秘密鍵の生成]をクリックして[キーを生成]を選ぶ
- jsonファイルのダウンロードが始まるのでservice-account.jsonとしてquickstart-nodejs/placeholdersディレクトリに保存する
サービスアカウントの詳細については公式ドキュメントを参照。
https://firebase.google.com/docs/admin/setup?hl=ja#initialize_the_sdk_in_non-google_environments
依存パッケージのインストール
npm install googleapis
サンプルプログラムの編集
quickstart-nodejs/messaging/index.jsを開く。
- 12行目の<YOUR-PROJECT-ID>を自身のプロジェクトIDに書きかえる
- 113~123行目のbuildCommonMessage関数において116行目の"topic:"項目を削除する
- 削除した"topic:"項目の代わりに"token:"項目として取得したトークン文字列を書く
設定できるフィールドについては公式ドキュメントを参照。
https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages?hl=ja
通知の送信
quickstart-nodejs/messagingディレクトリで以下のコマンドを実行する。
node index.js common-message
正しく設定できていればターミナルに以下のような送った通知の内容とレスポンス(message id)が表示される。
FCM request body for message:
{
"message": {
"token": "<TOKEN>",
"notification": {
"title": "FCM Notification",
"body": "Notification from FCM"
}
}
}
Message sent to Firebase for delivery, response:
{
"name": "projects/<PROJECT-ID>/messages/<MESSAGE ID>"
}
サンプルプログラムだと通知が2個送られてくる問題への対応
通知を送れるようにはなったが、なぜが2通届くという謎現象に悩まされた。
1通は自分が書き換えた通知だが、もう1通は
タイトル:Background Message Title
本文:Background Message body.
と全く無意味な通知内容。
調べた結果、トークンを取得する方のサンプルプログラムに2通目の謎通知を発出する部分を見つけた。
具体的にはquickstart-js/messaging/firebase-messaging-sw.jsの47〜58行目、messaging.onBackgroundMessage関数にて追加の通知登録が行われていた。
messaging.onBackgroundMessage(function(payload) {
console.log('[firebase-messaging-sw.js] Received background message ', payload);
// Customize notification here
const notificationTitle = 'Background Message Title';
const notificationOptions = {
body: 'Background Message body.',
icon: '/firebase-logo.png'
};
self.registration.showNotification(notificationTitle,
notificationOptions);
});
この関数のself.registration.showNotificationの部分(56,57行目)をコメントアウトしたところ無事に送りたい通知のみになった。
反映させるには、コメントアウト後にビルドとデプロイをし直して
npm run build # ビルド
firebase deploy # デプロイ
Webページ(https://<project_id>.firebaseapp.com)にアクセスする。
表示されたトークン文字列は変わっていなくても問題ない。
参考情報
Firebase Cloud Messagingの公式ドキュメント
https://firebase.google.com/docs/cloud-messaging?hl=ja
APIの移行情報
https://firebase.google.com/docs/cloud-messaging/migrate-v1?hl=ja