【Laravel】Firebase Cloud MessagingでHTTP v1を使用してAPIを実装する方法

この記事からわかること

  • LaravelFirebase Cloud Messaging通知方法
  • HTTP v1実装方法
  • Google Clientライブラリの導入
  • 特定デバイスグループだけに通知を送信するには?

index

[open]

\ アプリをリリースしました /

みんなの誕生日

友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-

posted withアプリーチ

環境

サーバー環境のFirebase Cloud Messaging

リモート通知が送信できるFirebase Cloud Messaging(FCM)はコンソールからの手動で通知を発行するだけでなく、サーバー環境を利用してエンドポイントに指定のパラメータを送信することも可能になっています。

【Swift/Firebase】リモートプッシュ通知の実装方法!Cloud Messagingの使い方

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の歯車マーク>プロジェクトの設定>全般から確認することができます。

【Swift/Firebase】Cloud MessagingでHTTP v1を使用して通知を発火する方法

以前のバージョンである「FCM HTTP API」を使用している場合は「HTTP v1 API」へ移行する必要があります。

OAuth2.0とは?

OAuth2.0とはインターネット上でユーザーの認証と認可を行うためのプロトコルです。ユーザーを認証することでアクセストークンを発行しそのトークンを利用して認証が必要なリソースにアクセスできるようになります。

実装方法

今回はバックエンドにLaravelを利用している記事を参考に実装していきたいと思います。APIを実装できるLaravelプロジェクトがある前提で進めていきます。

参考文献:Qiita PHP/LaravelでFCMpush通知を実装した件

参考文献:公式リファレンス:以前の HTTP から HTTP v1 に移行する

  1. LaravelにGoogle APIClientライブラリを導入
  2. 秘密鍵を取得
  3. Laravelのenvに反映
  4. envの情報を取得したconfigを追加
  5. Controllerに通知発火メソッドを用意
  6. ルーティング

iOSやAndroidなどのモバイルアプリで利用する場合はここで作成したAPIを叩くだけで利用することができるようになります。iOSアプリなどの場合はFirebaseに事前にKey(.p8ファイル)をアップロードしたり、プロビジョニングプロファイルを作成したりなどやることが多いので以下の記事を参考にしてください。

1.LaravelにGoogle APIClientライブラリを導入

まずはLaravelでOAuth2.0のアクセストークンを取得できるようにするためにGoogle APIClientライブラリを導入していきます。

公式リファレンス: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登録トークンの取得方法は以下の記事を参考にしてください。

【SwiftUI】通知機能の実装方法!ローカル通知が届いている要素

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index