はじめに
Laravelを使った個人開発をしており、詳しくはこの記事でまとめています。
今回の開発では認証機能にFirebase Authenticationを採用し、バックエンドアプリからFirebaseに接続する必要がありました。公式のFirebase Admin SDKはPHPをサポートしておらず、サードパーティSDKであるkreait/firebase-phpを利用しました。
FirebaseにこのSDKを通じて連携をする上で、躓いたポイントを忘れないように記録しておきたいと思います。
開発環境
- OS バージョン
- Windows 11
- バックエンド
- Laravel 11.41.3
手順と生じた問題
1. SDKとLaravel用のpackageをインストール
SDKのgithubページのREADMEを参考にインストールします。
https://github.com/kreait/firebase-php
https://github.com/kreait/laravel-firebase
composer require kreait/firebase-php
composer require kreait/laravel-firebase
2. SDKの設定ファイルを公開
以下のコマンドでconfig配下にfirebase.phpがコピーされます。カスタム設定ができますが、この記事では特に編集しません。
php artisan vendor:publish --provider="Kreait\Laravel\Firebase\ServiceProvider" --tag=config
3. サービスアカウントの秘密鍵をダウンロード
Jsonフォーマットの秘密鍵をプロジェクトコンソールのサービスアカウントタブからダウンロードできます。サービスアカウントを作成していない場合は、まず作成する必要があります。
ダウンロードできたら、ファイル名をfirebase-auth.jsonに変更し、storage/app/配下に設置します。セキュリティセーフのため、gitignoreに追加します。
4. 環境変数を設定
.envファイルに3で設置したJsonファイルの絶対パスの環境変数を設定します。
FIREBASE_CREDENTIALS=storage/app/firebase-auth.json
5. Firebase認証用のコントローラーを用意
<?php
namespace App\Http\Controllers;
use Kreait\Laravel\Firebase\Facades\Firebase;
class FirebaseUserController extends Controller
{
protected $auth;
public function __construct()
{
// authコンポーネントのインスタンスを格納
$this->auth = Firebase::auth();
}
public function getAllUsers()
{
// Firebaseプロジェクトに登録されている全ユーザーを取得
$users = $this->auth->listUsers();
return response()->json($users);
}
}
api.phpにルーティングを追記します。
...
use App\Http\Controllers\FirebaseUserController;
...
Route::get('/users',[FirebaseUserController::class, 'getAllUsers']);
6. 動作確認
Firebaseコンソールから[Authentication]->[ユーザーの追加]でテストユーザーを作成します。
ローカルサーバーを起動し、ブラウザやPostmanで先ほどのAPIエンドポイントにアクセスしてみます。これで作成したテストユーザーが返ってきたら連携成功です。
http://127.0.0.1:8000/api/users にGETリクエスト
すると、空のJsonが返ってきます。
{}
エラーも出ていないし、レスポンスが返ってきてるので、Firebaseとの連携はできているはずです。ここで原因がわからずドキュメントとにらめっこしていると、listUsers()は配列ではなく、Generatorを返すと書いてありました。
そのため、foreachなどでデータを生成し、新たな配列を返す必要がありました。
To enhance performance and prevent memory issues when retrieving a huge amount of users, this methods returns a
Generator
.
public function getAllUsers()
{
$users = $this->auth->listUsers();
// foreachで各ユーザーデータをGenerate
$array_users = [];
foreach ($users as $user) {
$array_users[] = $user;
}
return response()->json($array_users);
}
これでユーザーデータを取得することができました!
7. 他の取得メソッド(queryUsers())
ドキュメントに記載のqueryUsers()でも取得できるか試してみます。UserQueryの値で取得条件を設定できます。
https://firebase-php.readthedocs.io/en/7.16.1/user-management.html#query-users
...
use Kreait\Firebase\Auth\UserQuery;
...
public function getAllUsers()
{
# Building a user query object
$userQuery = UserQuery::all()
->sortedBy(UserQuery::FIELD_USER_EMAIL)
->inDescendingOrder()
->withLimit(499); # The maximum supported limit is 500
}
$users = $auth->queryUsers($userQuery);
同じく、http://127.0.0.1:8000/api/users にGETリクエスト
すると、別のエラーが出ました。
Kreait\Firebase\Exception\Auth\AuthError
cURL error 60: SSL certificate problem: unable to get local issuer certificate (see https://curl.haxx.se/libcurl/c/libcurl-errors.html)
原因としては、リクエストの際に、FirebaseからSSL証明書を受け取り、その証明書が認証局によって発行されたかどうかものかどうかをCA証明書バンドルというものを使って確認します。しかし、Windows環境ではその証明書バンドルを手動で設定する必要があるため、それが見つからないというエラーです。
下記サイトから最新のcacert.pemをダウンロードし、
下記フォルダに保存します。
{phpのインストール先パス}/php-8.3.13-Win32-vs16-x64/extras/ssl/
またphp.iniのcurl.cainfoをコメントアウトし、cacert.pemまでの絶対パスを設定します。
curl.cainfo="{phpのインストール先パス}\php-8.3.13-Win32-vs16-x64\extras\ssl\cacert.pem"
ローカルサーバーを再度立ち上げます。
すると、今度はユーザーが取得できているはずです。
参考記事