FCMから通知メッセージを送る
以前の記事でAndroidから通知(Notification)を送る実装をしました。
実際の運用はサーバーから任意のタイミングで通知を生成してFCMに投げるということになるかと思います。このFCMを投げるプロトコルが「FCM HTTP v1 API」というわけです。
現在FCMが提供しているプロトコルは
- FCM HTTP v1 API
- レガシー HTTP プロトコル
- レガシー XMPP プロトコル
の3つがありますが、推奨は1です。2と3はレガシーと名前がついている通り現在は非推奨ですが、ブログなどの実装例では2が多いです。OAuth 2.0 アクセス トークン生成を利用せず、固定のトークンを取得すれば比較的簡単に実装できるので多いのかなと思います。
しかし今後は1のみになっていくのは間違いないと思いますので実装をトライしてみました。
PHPでFCM HTTP v1 APIを叩きたい
FCM HTTP v1 APIを利用する際、Googleが公式にサポートする言語(例示されている言語)として
- Node.js
- Java
- Python
- Go
- C#
となっていて、OAuth 2.0 アクセス トークン生成には
- Node.js
- Java
- Python
しかないようです。利用しているバリューサーバーの利用可能言語は
となっており、通常であればPythonを使えばいいのかなと思いましたが…
サーバーでPythonを使ったことがないのでPHPでゴリ押ししたい!!
という理由からPHPで実装してみます(需要も多そうだし)。PHPの公式サンプルは探してもないので、非公式ライブラリを用いての実装になるわけです。
ググってみるとgoogle-api-php-clientを用いた実装例が海外を中心に多く公開されていましたのでこれを使っていきたいと思います。
サーバーにgoogle-api-php-clientをインストール
この辺は人によって環境が違うのでレンタルサーバーの仕様と方法をよく読んで進めます。肝になる部分は
- SSH接続ができる(Composerを使う為)
- Composerが利用できる(google-api-php-clientのインストールする為)
- PHP 5.6.0 or higherである(google-api-php-clientを使う為)
あたりとおもいます。
ここからはバリューサーバーでの方法を記しておきます。前提として「SSHを若干でも触ったことがある」「FTPでファイルの転送ができる」「Linuxを触ったことがある(viエディタなど)」程度の知識は必要です。
推奨されてる方法である「Composerを使ってgoogle-api-php-clientをサーバーにインストール」していきます。Composerとは依存しているライブラリを一発でインストールしてくれる便利なものらしいです。
Composerを使うためにはSSH接続をしなければなりません。この辺を参考にして接続できるようにします。クライアントはラズパイがらみで使い慣れたTeraTermにしました。
SSH接続が完了したらComposer使えるようにします。バリューサーバーではCLI版で実行しなければならないみたいなので下のサイトを参考にして
.bashrcへエイリアスを登録して起動できるようにした。Composerのアップデートはせずに
1 2 3 4 5 6 7 8 9 10 |
# .bashrc # Source global definitions if [ -f /etc/bashrc ]; then . /etc/bashrc fi # User specific aliases and functions # 追記 alias composer='php56cli /usr/bin/composer' |
phpも5.6のままにしときました。
そして任意のディレクトリで
composer require google/apiclient:”^2.7″
を実行したら無事にインストール完了できたようです。ここまできれば後はらくちんです。別なレンタルサーバーを利用している人などは仕様を確認してみる必要があります。
phpで実際FCMを送ってみる
ベースとなるsend.phpは下を参考にしています。
作業内容としては
- auth.jsonの取得
- Firebase project IDの確認
- $messageの内容の編集
- send.phpでのテスト
となります。
1は下の「認証情報を手動で提供する」を参考にしてjsonファイルを取得します。ダウンロードしたjsonファイルをauth.jsonとします。
2はFirebaseで該当アプリの設定-全般からプロジェクトIDがあるのでそれをメモしときます。
send.phpの書き換えるべき部位は下のような感じです
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
<?php /** * This serves as an example of how to use the Google API PHP Client * with Firebase Cloud Messaging Service. * * The client can be found here: * https://github.com/google/google-api-php-client * * At the time of writing this, there's no Service object for the correct * scope for Firebase Messaging, so here's an example of how this can be * done with provididing the scope manually. * * Info regarding authorization and requests can be found here: * https://firebase.google.com/docs/cloud-messaging/server */ require 'vendor/autoload.php'; // インストールしたgoogle-api-php-clientのパスに合わせて変更 $client = new Google_Client(); // Authentication with the GOOGLE_APPLICATION_CREDENTIALS environment variable $client->useApplicationDefaultCredentials(); // Alternatively, provide the JSON authentication file directly. $client->setAuthConfig(__DIR__.'/auth.json'); // 1で取得したjsonファイルをサーバーに上げてパスに合わせて変更 // Add the scope as a string (multiple scopes can be provided as an array) $client->addScope('https://www.googleapis.com/auth/firebase.messaging'); // Returns an instance of GuzzleHttp\Client that authenticates with the Google API. $httpClient = $client->authorize(); // Your Firebase project ID $project = "myproject-4e6ed"; // 2で取得したプロジェクト名に変更 // Creates a notification for subscribers to the debug topic $message = [ "message" => [ "topic" => "debug", "notification" => [ "body" => "This is an FCM notification message!", "title" => "FCM Message", ] ] ]; // Send the Push Notification - use $response to inspect success or errors $response = $httpClient->post("https://fcm.googleapis.com/v1/projects/{$project}/messages:send", ['json' => $message]); |
3の$messageですが、上のサンプルの例ではdebugトピックの購読者に通知を送るようになっているのでこれでphpが正しく通知を出せるかテストしてみるのがいいと思います。
テストの通知を確認出来たので、すこし拡張してみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
~ 略 ~ $title = "通知タイトル"; $body = "通知内容です"; $topic = "hogehoge"; //このトピックの指定は/topics/[トピック名]ではなくトピック名のみでOKでした //メッセージの有効時間の設定 $sec = 2 * 60 * 60; //有効時間は2時間 $timestamp = time() + $sec; $sec_st = $sec . "s"; // Creates a notification for subscribers to the debug topic $message = [ "message" => [ "topic" => (string)$topic, "notification" => [ "body" => (string)$body, "title" => (string)$title , ], "apns" => [ "headers" => [ "apns-priority" => "10", "apns-expiration" => (string)$timestamp, ], "payload" => [ "aps" => [ "sound" => "default", ] ] ], "android" => [ "priority" => "high", "ttl" => (string)$sec_st, "notification" => [ "sound" => "default", ] ], ] ]; ~ 略 ~ |
上の例はメッセージの有効期限を2時間に設定し音を鳴らすメッセージです。apns(pple push notification service)とandroidで設定が異なるので別途指定します。通知のタイトルと内容は共通です。$titleと$bodyを指定すれば通知を行えます。メッセージは色々指定できるようなので各自調べてみてください。
公開中アプリ「九九おぼえちゃお」のランキング通知に実装してみました。定期的にユーザーにランキングを通知する仕組みです。cronを使ってphpを叩いています。
まとめ
正直、このステップはとってもめんどくさいですw。いろいろやっていて
やっぱ簡単なレガシーHTTPプロトコルでいいかな?
と何度も思いました。いつか、いきなり使えなくなるよりはいいと思いますのでやったことは無駄ではなかった・・・と思いたいですw