FlutterでGemini APIなどのAIにリクエストするときの環境構築メモ

1. 全体アーキテクチャと役割

役割技術スタックやること
アプリ (Front)FlutterユーザーUI。Cloud Functions を叩く。Firestore/Storage は直接読み書きする。
門番 (Back)Cloud FunctionsGemini APIの隠蔽。レートリミット管理。JSON整形。
DB (Limit)Firestoreレートリミットの回数カウント用(管理者が読み書き)。
AIGemini APIプロンプトを受け取り、JSONを返す。

2. 【最重要】プロジェクト接続先の管理

ここが今回の一番のハマりポイントでした。「フロントとバックエンドは、別々の設定を見ている」 という点です。

❌ よくある事故(ねじれ現象)

ターミナルで firebase use だけしてデプロイすると…

  • バックエンドは「開発環境」にデプロイされたのに、
  • アプリは「本番環境」を見に行こうとしてエラーになる(またはその逆)。

✅ 正しい切り替え手順(2ステップ必須)

環境(Dev / Prodなど)を変えるときは、必ず両方やります。

対象見ている場所切り替えコマンド
Cloud Functions
(サーバー側)
.firebaserc
(CLIの設定)
firebase use <プロジェクトID>

firebase deploy
Flutterアプリ
(スマホ側)
lib/firebase_options.dart
(コード内の設定)
flutterfire configure
(対話形式でプロジェクト選択)

3. Gemini API の実装ポイント

  • JSONで返す: プロンプトで指示するだけでなく、responseMimeType: 'application/json' を設定すると確実。
  • パース: 返ってきた文字列を JSON.parse(text) してオブジェクトにしてからフロントに返す。
  • ログ: クラウドのログには severitymessage が付くが、return するデータ自体は綺麗なので気にしなくてOK。

4. レートリミット(Firestore)の実装

Cloudflare D1 ではなく Firestore を採用しました。Google内部通信なので高速で、無料枠も大きいです。

  • ライブラリ: バックエンド側では firebase-admin を使う(npm install firebase-admin)。
  • 認証: initializeApp()(引数なし)でOK。サーバーの特権(Admin)で動くのでAPIキー不要。
  • ロジック:「Lazy Reset(遅延リセット)」方式を採用。
    • Redisのように勝手に消えないので、「アクセスされた瞬間に resetAt を過ぎていたらカウントをリセットする」というコードを書く。
  • データ作成: 事前にコンソールで作る必要なし。コードが set() した瞬間にドキュメントは自動生成される。

5. セキュリティの考え方

  • Gemini APIキー: 「無制限のクレジットカード」と同じ。絶対にフロント(アプリ)には置かない。Functionsに隠す。
  • Firestore / Storage: アプリから直接叩いてOK。
    • なぜ? → アプリが持っているキーは「住所」だけで、「鍵(権限)」はサーバー側の Security RulesFirebase Auth で管理されているから。
  • App Check: アプリが「本物である」ことを証明する仕組み。導入済み(keytool でSHA-256登録、pub add)。

6. 開発時の便利コマンド集

# 1. サーバー側のプロジェクト切り替え
firebase use <プロジェクトID>

# 2. 関数をデプロイ
firebase deploy --only functions

# 3. アプリ側のプロジェクト設定を更新(これが重要!)
flutterfire configure

# 4. パッケージ追加(必要になったら)
# サーバー側
cd functions && npm install <パッケージ名>
# アプリ側
flutter pub add <パッケージ名>

コメント

タイトルとURLをコピーしました