【Laravel】Firebase Cloud MessagingでHTTP v1を使用してAPIを実装する方法
この記事からわかること
- LaravelでFirebase Cloud Messagingの通知方法
- HTTP v1の実装方法
- Google Clientライブラリの導入
- 特定のデバイスやグループだけに通知を送信するには?
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
環境
- Laravel:8.83.27
- Laravel Installer:4.2.9
- PHP(MAMP): 8.0.8
- macOS:Sonoma 14.1
サーバー環境のFirebase Cloud Messaging
リモート通知が送信できるFirebase Cloud Messaging(FCM)はコンソールからの手動で通知を発行するだけでなく、サーバー環境を利用してエンドポイントに指定のパラメータを送信することも可能になっています。
HTTP v1 API
現在のFCMのサーバー環境を利用した通知発火の仕組みは「HTTP v1 API」です。「HTTP v1 API」は認証方法にOAuth2.0のアクセストークンを活用する様に変更されたためセキュリティが向上しました。
エンドポイントも以下の様に変更されています。
旧
POST https://fcm.googleapis.com/fcm/send
新
POST https://fcm.googleapis.com/v1/projects/${projectID}/messages:send
エンドポイントに含める${projectID}
はFirebaseの歯車マーク>プロジェクトの設定>全般から確認することができます。
以前のバージョンである「FCM HTTP API」を使用している場合は「HTTP v1 API」へ移行する必要があります。
OAuth2.0とは?
OAuth2.0とはインターネット上でユーザーの認証と認可を行うためのプロトコルです。ユーザーを認証することでアクセストークンを発行しそのトークンを利用して認証が必要なリソースにアクセスできるようになります。
実装方法
今回はバックエンドにLaravelを利用している記事を参考に実装していきたいと思います。APIを実装できるLaravelプロジェクトがある前提で進めていきます。
参考文献:Qiita PHP/LaravelでFCMpush通知を実装した件
参考文献:公式リファレンス:以前の HTTP から HTTP v1 に移行する
- LaravelにGoogle APIClientライブラリを導入
- 秘密鍵を取得
- Laravelのenvに反映
- envの情報を取得したconfigを追加
- Controllerに通知発火メソッドを用意
- ルーティング
iOSやAndroidなどのモバイルアプリで利用する場合はここで作成したAPIを叩くだけで利用することができるようになります。iOSアプリなどの場合はFirebaseに事前にKey(.p8ファイル)をアップロードしたり、プロビジョニングプロファイルを作成したりなどやることが多いので以下の記事を参考にしてください。
1.LaravelにGoogle APIClientライブラリを導入
まずはLaravelでOAuth2.0のアクセストークンを取得できるようにするためにGoogle APIClient
ライブラリを導入していきます。
Laravelのプロジェクトにカレントディレクトリを合わせ以下のコマンドを実行します。インストールが無事完了したら次に進みます。
$ composer require google/apiclient:^2.15.0
バージョンにロックが掛けられていて失敗する場合は--with-all-dependencies
を付与して実行してみてください。
$ composer require google/apiclient:^2.15.0 --with-all-dependencies
もし以下のようなエラーが発生した場合はPHPのバージョンが高すぎることが原因(私の場合は8.2だった)なのでPHPのバージョンを7.2〜8.0
の間に下げる必要があります。
Problem 1
- phpspec/prophecy 1.14.0 requires php ^7.2 || ~8.0, <8.2 -> your php version (8.2.8) does not satisfy that requirement.
- phpunit/phpunit 9.5.10 requires phpspec/prophecy ^1.12.1 -> satisfiable by phpspec/prophecy[1.14.0].
- phpunit/phpunit is locked to version 9.5.10 and an update of this package was not requested.
Installation failed, reverting ./composer.json and ./composer.lock to their original content.
PHPのバージョンを下げるにはcomposer config platform.php XXX
に下げたいバージョンを指定してcomposer update
を実行すればOKです。
$ composer config platform.php 8.0
$ composer update
2.秘密鍵(projectid-firebase-adminsdk-XXXXX.json)をダウンロード
続いてFirebaseの秘密鍵(projectid-firebase-adminsdk-XXXXX.json)を取得します。このファイルは中身を確認してLaravel側のenvファイルにコピペするために利用するだけになります。
秘密鍵はFirebaseの歯車マーク>サービスアカウント>新しい秘密鍵を生成からダウンロードすることができます。このファイルは秘匿情報を含んでいるファイルなのでGitHubなどにコミットしないように注意してください。
3.Laravelのenvに反映
次に秘密鍵の中身を開いて中にあるJSONの値を.env
ファイルにコピペしていきます。PUSH_API
には自身のプロジェクトIDを入れたエンドポイントを記述します。
TYPE="秘密鍵の内容"
PROJECT_ID="秘密鍵の内容"
PRIVATE_KEY_ID="秘密鍵の内容"
PRIVATE_KEY="秘密鍵の内容"
CLIENT_EMAIL="秘密鍵の内容"
CLIENT_ID="秘密鍵の内容"
AUTH_URI="秘密鍵の内容"
TOKEN_URI="秘密鍵の内容"
AUTH_PROVIDER_X509_CERT_URL="秘密鍵の内容"
CLIENT_X509_CERT_URL="秘密鍵の内容"
PUSH_API="https://fcm.googleapis.com/v1/projects/${projectID}/messages:send"
4.envの情報を取得したconfigを追加
続いて.env
ファイルに記述した値を取得したconfigファイルを作成しておきます。作成するのはconfigディレクトリの中です。
<?php
/*
|--------------------------------------------------------------------------
| Firebase Cloud Messaging の 秘密鍵JSONのconfig
|--------------------------------------------------------------------------
|
*/
return [
'auth' => [
'type' => env('TYPE'),
'project_id' => env('PROJECT_ID'),
'private_key_id' => env('PRIVATE_KEY_ID'),
'private_key' => env('PRIVATE_KEY'),
'client_email' => env('CLIENT_EMAIL'),
'client_id' => env('CLIENT_ID'),
'auth_uri' => env('AUTH_URI'),
'token_uri' => env('TOKEN_URI'),
'auth_provider_x509_cert_url' => env('AUTH_PROVIDER_X509_CERT_URL'),
'client_x509_cert_url' => env('CLIENT_X509_CERT_URL'),
],
'push_api' => env('PUSH_API'),
];
5.Controllerに通知発火メソッドを用意
続いてControllerにリクエストを受けた際に通知を発火する処理を実装していきます。ここでGoogle_Client
を使用して認証情報を取得しFCMのエンドポイントに対して通知に必要な情報を込めてPOST送信しています、
// URLの引数でそれぞれを受け取る
public function fcmAPINotify(string $token, string $title, string $messageBody): void
{
// Google Clientをインスタンス化
$googleClient = new Google_Client();
// 認証情報を設定ファイルから取得して設定
$googleClient->setAuthConfig(config('fcm.auth'));
// FCMにアクセスするためのスコープを追加します
$googleClient->addScope('https://www.googleapis.com/auth/firebase.messaging');
// 認証されたHTTPクライアントを取得
$httpClient = $googleClient->authorize();
// 送信するメッセージの本体を定義する
$data = [
'message' => [
'token' => $token, // 送信先のデバイストークン
'notification' => [
'body' => $messageBody, // 通知の本文
'title' => $title, // 通知のタイトル
],
'apns' => [ // Apple Push Notification Service用のペイロード
'payload' => [
'aps' => [
'alert' => [
'title' => $title, // 通知のタイトル
'body' => $messageBody // 通知の本文
]
]
]
],
'android' => [ // Android用のペイロード
'priority' => 'high', // 高優先度で通知を送信
'notification' => [
'sound' => 'default', // 通知音をデフォルトに設定
]
],
]
];
// FCMに向けてPOSTリクエストを送信する
$response = $httpClient->post(config('fcm.push_api'), [
'json' => $data // メッセージデータをJSON形式で送信
]);
// エラーハンドリングを行う
if ($response->getStatusCode() !== 200) {
// ステータスコードが200以外の場合エラーを投げる
throw new \Exception('FCM push notification failed: ' . $response->getBody());
}
}
6.ルーティング
最後にroutes/api.php
の中にルーティングを定義します。パラメーターにデバイス(FCM登録)トークンと通知のタイトル、メッセージを受け取れるようにしてあります。routes/api.php
に実装したのでURLを叩くときはhttps://XXXXXX.com/api/notify/{token}/{title}/{messageBody}
形式でapi
を追加するのを忘れないようにしてください。
Route::get(
'/notify/{token}/{title}/{messageBody}',
'App\Http\Controllers\NotifyController@fcmAPINotify'
);
Route::post(
'/notify/{token}/{title}/{messageBody}',
'App\Http\Controllers\NotifyController@fcmAPINotify'
);
これで実装は完了したのでモバイルアプリなどから必要な情報を含めてこのAPIを叩けばリモートプッシュ通知が届くようになります。URLのパラメータFCM登録トークンの取得方法は以下の記事を参考にしてください。
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。