こんばんは!
アドベントカレンダー4日目を担当します、サーバーサイドエンジニアの@takapon21です
よろしくお願いします。
今回は、PHP/Laravelを使用してFCM Push通知を送信する
という実装についてのまとめを記載したいと思います。
firebase公式でサポートしてくれないPHP/Laravelを用いてどうしても実装したいんだ!!
という方向けに書いていきます。
実際私も参考文献が乏しすぎて苦労しました。備忘録に近いです
やりたいこと
LaravelからiOSデバイス、Androidデバイスにpush通知を送りたい
今回はWeb Push通知ではなく(googleカレンダーが10分前くらいに会議を教えてくれるアレ)
Laravelを起点として、FCMを利用し、google, appleが提供するpush通知サーバーを経由して各デバイスにpush通知を送信する
という実装をします。
今回省略すること
push通知を送信するために、デバイスのトークンが必要です
このトークンは、「誰に送信するか」を指定するために使用します。
ネイティブアプリケーション側の仕事なので、「トークンはもう取得している」前提で書いていきます
では、始めていきましょう!
① firebase側の準備
FCMを利用する旨の設定をしてください。
この辺の細かい設定は省略しますが、やってほしいことは全部で以下の2つだけです!!
- (Appleアプリを作成される方)、APNs認証キー又はAPNs証明書をアップロードしてください
- サービスアカウントから秘密鍵(project_name-firebase-adminsdk-hogefuga.json)をダウンロードしてください
ここをスキップしますと、以降の作業をいくら頑張ってもpush通知は送信できません
② 秘密鍵を開いてみる
先ほどダウンロードしたサービスアカウントの秘密鍵を覗いてみましょう
これは何度も言いますが、秘密鍵は重要な秘匿情報に分類しますので、生でgithubにアップロードしないようにご注意ください。(AWSのパラメータストアなど使用しましょう)
{
"type": "service_account",
"project_id": "",
"private_key_id": "",
"private_key": "-----BEGIN PRIVATE KEY----- yeeeeeeeeeeeah -----END PRIVATE KEY-----\n",
"client_email": "firebase-adminsdk@my-project.iam.gserviceaccount.com",
"client_id": "123454321",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-my-project.iam.gserviceaccount.com",
"universe_domain": "googleapis.com"
}
このようなjsonファイルが取得できましたらOKとなります。
何度も言いますが、Laravel側でconfigファイルやenvファイルに記載する際は生データをコミットかけないようにご注意ください
③ push通知を飛ばすエンドポイントを作る
下記のコードを環境変数として登録してください。
こちらのエンドポイントにpush通知をリクエストすることになります
https://fcm.googleapis.com/v1/projects/${PROJECT_NAME}/messages:send
プロジェクト名で置き換えて、登録します。
何度も言いますが、秘匿情報は生でコミットかけないようにご注意ください
以降
env: PUSH_API
config: push_api => env('PUSH_API')
として活用していきます
④ Laravel側の実装をしていきます
今回はHTTP v1 APIを利用した実装をしていきます。
よくwebで「Laravel FCM push通知」と調べますと、ライブラリを利用した実装などをお見受けしますが、このHTTP v1 API に対応できていないものが含まれていますのでご注意ください。
上記のような実装でも動かないこともないですが、
公式から発表されていますようにいつ廃止されるか分かりませんのでご注意くださいませ
HTTP v1 APIについて
https://firebase.google.com/docs/cloud-messaging/migrate-v1?hl=ja
v1に以降することでOAuth2.0アクセストークンが認証で必要になります。
公式ドキュメントではこの辺です
これを突破するために、Google Clientライブラリを使用します
Google APIClientライブラリのインストール
使用ライブラリ: https://github.com/googleapis/google-api-php-client
まずは下記のコマンドを入力してGoogle API Clientライブラリをインストールしましょう
$ composer require google/apiclient:^2.15.0
envの準備
先ほどダウンロードしたjsonファイルをenvに登録していきます
下記はキー名の例として書いておきます
// 認証関係
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=""
// FCMエンドポイント
PUSH_API=""
configの準備
環境変数を使用しますので、configファイルも作成しておきましょう
今回はfirebase.phpを新規作成しました
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'),
];
push通知を実装していきます
完成形です
public function notify(string $token, string $title, string $messageBody): void
{
$googleClient = new Google_client;
$googleClient->useApplicationDefaultCredentials();
// 先ほど設定した認証情報を用います
$googleClient->setAuthConfig(config('firebase.auth'));
// FCMにアクセスするためのスコープを追加します
$googleClient->addScope('https://www.googleapis.com/auth/firebase.messaging');
// ここで認証されたHTTPクライアントを取得
$httpClient = $googleClient->authorize();
// テストで送信するメッセージを作成します
$title = "試しに送信するタイトル";
$messageBody = "試しに送信するメッセージ本文";
// 送信するメッセージの本体
$data = [
'message' => [
// 送信対象者(1名分だけ有効です)
'token' => $token,
'notification' => [
'body' => $title,
'title' => $messageBody,
],
'apns' => [
'payload' => [
'aps' => [
'alert' => [
'title' => $title,
'body' => $messageBody
]
]
]
],
"android" => [
"priority" => "high",
"notification" => [
"sound" => "default",
]
],
]
];
// FCMに向けてPOSTリクエストを飛ばします
$httpClient->post(config('firebase.push_api'), ['json' => $data]);
}
メッセージ本文の構成はこれ以外にもオプションがつけられます
https://firebase.google.com/docs/cloud-messaging/concept-options?hl=ja
こちらからご確認くださいませ
試しに動かしてみる
はい、push通知の受信に成功しました!
いかがでしたか?
firebaseのFCMを利用する
↓
PHPは公式でサポートされていない!!詰んだ!!
で諦めず、Google API Clientを使用する
という選択肢が新しく増えたのではないでしょうか?
ぜひこのコードをベースとして参考にしていただけますと幸甚です
参考文献