💻

【PHP】PHP(Cake4)からFCMでPush通知を送った時の話

2022/03/04に公開
4

過去の案件で自前のPHPアプリケーションからPush通知を送信した話です。
参考記事がだいぶ参考になりましたが、自分なりに補完した内容です。

FCMを経由してPush通知を送る方法は、大きく2つあるかと思います。

  1. WEBフロントから送る
  2. バックエンドサーバなどのサーバから送る

本記事は、「2.」の方を対象に書いています。

環境

  • Windows(10)
  • Firebase
  • PHP(7.3)
    • Cake(4.3.5)
  • Composer

事前準備

  • Firebaseの登録
  • Push通知を受け取れるアプリ
    受け取れなくても確認はできます。

手順

firebaseの準備

1. 送信者IDを取得する

送信者IDを取得します。

2. 認証用のJSONを取得する

赤枠のボタンをクリックして認証用のJSONを取得します。

後程[file_get_contents]で内容を読み込みますので、Cakeプロジェクト内とかに配置してください。

Cakeアプリの準備

前提として、php.iniなどの設定は完了していることを想定してます。

1. Cakeプロジェクトを作成

コマンドプロンプトを開いて、下記のコマンドを実行します。

composer create-project --prefer-dist cakephp/app {任意のプロジェクト名}

2. Googleクライアントをインストール

PHPには公式のFCM用FirebaseAdminSDKが提供されていないので、GoogleApiを使用して認証を行うので、Composerを使用してGoogleクライアントをインストールします。

cd {プロジェクト名}
composer require google/apiclient:^2.12.1

3. バッチプロジェクトを作成

cd {プロジェクト名}
bin\cake bake command {任意のファイル名}

とりあえず、生成したPHPファイルの中身は、こんな感じに修正します。

生成したPHPファイル.php
<?php
declare(strict_types=1);

namespace App\Command;

use Cake\Command\Command;
use Cake\Console\Arguments;
use Cake\Console\ConsoleIo;
use Google_client;

/**
 * PushNotification command.
 */
class PushNotificationCommand extends Command
{
    /**
     * Implement this method with your command's logic.
     *
     * @param \Cake\Console\Arguments $args The command arguments.
     * @param \Cake\Console\ConsoleIo $io The console io
     * @return null|void|int The exit code or null for success
     */
    public function execute(Arguments $args, ConsoleIo $io)
    {
        $authJson = file_get_contents({認証用のJSONのファイルパス});
        $authData = json_decode($authJson, true);

        $googleClient = new Google_client;
        $googleClient->useApplicationDefaultCredentials();
        $googleClient->setAuthConfig($authData);
        $googleClient->addScope('https://www.googleapis.com/auth/firebase.messaging');
        $httpClient = $googleClient->authorize();

        $data = [
            'message' => 
                [
                    'token' => '{Push通知を送りたい端末から取得したToken}',
                    'notification' => 
                        [
                            'body' => '通知がありまする。',
                            'title' => 'タイトルでござる'
                        ]
                ]
            ];
        $fcmApi = 'https://fcm.googleapis.com/v1/projects/{取得した送信者ID}/messages:send';
        $result = $httpClient->post($fcmApi, ['json' => $data]);
        $this->log(print_r($result, true), LOG_DEBUG);
    }
}

4. 動作確認

下記のコマンドを実行します。

bin\cake {作成したコマンド}

コンソールに下記のようにレスポンスとなっていれば送信できているはずです。

2022-03-04 02:59:08 notice: GuzzleHttp\Psr7\Response Object
(
    [reasonPhrase:GuzzleHttp\Psr7\Response:private] => OK
    [statusCode:GuzzleHttp\Psr7\Response:private] => 200
    [headers:GuzzleHttp\Psr7\Response:private] => Array
        (
	:以下略

ちなみに、アプリではこんな感じ

Firebase側の確認をするのでしたら、
エンゲージメント>Cloud Messaging>レポート
にある『送信数』がカウントアップされていると思います。

あとがき

過去に同じことしていらっしゃる方がいて大変ありがたいですね。
実はJava(Spring)でも同じことをしたのですが、PHPの情報もあってよかったです。
にしても、GoogleAPIはもう少し踏み込んで理解したいと思いました。
他のアプリケーションを作ってるときも出現したので・・・笑

今回Flutterアプリも一緒に作ったのですが、以前受け取り用アプリ作った時より、手順変わってたので、別途記事に出来たらします。

関連記事

参考記事

Github

pushnotification_sample

Discussion

SPJ_中村SPJ_中村

質問失礼いたします。
本記事はios・androidについて特に記述はございませんが、
Firebaseにiosアプリ、androidアプリの登録が完了していれば端末トークンを指定してあげることで自動でios・androidを識別し通知してくれる認識で問題なかったでしょうか。

ご回答いただけますと幸いです。
よろしくお願いいたします。

びぃぐるびぃぐる

ご質問ありがとうございます。

Push通知を送信するWEBアプリが登録してあるプロジェクトへiOS、Androidアプリの登録完了している
スマホアプリを起動して端末トークンを取得している
PHP側へハードコーディングなどで端末トークンを記述する
上記が設定が問題なければ、バッチ実行時に指定の端末を識別してPush通知を送信してくれるはずです。
また、各設定を下記にて、確認することができると思います。
①PHPのバッチ実行時にFirebaseのCloud Messagingにキューがたまっている
 →PHPとFirebase疎通OK
②Firebaseのコンソール(Cloud Messaging)から指定の端末へPush通知を送信する
 →Firebaseとアプリの疎通OK

(久しぶり「Cloud Messaging」をのぞいたら記事を書いた当時からFirebaseのUIが更新されていそうなので、本記事の更新とともに、アプリ側の記事を追加していこうと思います。)

情報が古くて申し訳ありませんが、
ご確認よろしくお願いいたします。

びぃぐるびぃぐる

遅くなりました。
Firebase側のプロジェクトに対象OS(iOS/Android)を追加し、アプリ側の実装でfirebaseのTokenを取得し、取得したTokenに対してPush通知を送信すればFirebase側で対象の端末へ通知を送ってくれます。

SPJ_中村SPJ_中村

ご確認ありがとうございます。
無事、firebase経由でandroid、iosともにプッシュ通知の動作を確認しました。
firebaseですと従量課金制ですので月/50000プッシュと制限はありますが、問題なさそうです。

先月、この場で確証を得られたため実装に踏み切ることが出来ました。
本当にありがとうございました。