Skip to main content

第12章:AIを守る(Firebase AI Logic × App Check)🤖🧿

この章でやるのはコレ👇✨

  • ✅ 「AI整形ボタン(要約・言い換え)」をアプリに実装する
  • App Check を効かせて “正規アプリ以外” のAI呼び出しを落とす🧿
  • レート制限(Quota)で破産を防ぐ💸🚫
  • AI監視(AI monitoring)で異常に気づける👀📈

1) まず腹落ち:AIは “お金が燃えやすいAPI” 🔥💸

AI Cost Risk

FirestoreやStorageも狙われるけど、AIは特にヤバいです😇 理由はシンプル👇

  • 1回のリクエストが高い(しかも出力が長いとさらに高い)💸
  • 連打・自動化が簡単(ボットが大好物)🤖
  • **「想定外の使われ方」**が起きやすい(プロンプト悪用、無限生成など)🌀

だからAIは、最初から守りを前提に設計した方がラクです🙂🧿


2) Firebase AI Logic で “守れるAI呼び出し” にする🛡️🤖

AI Proxy Gate

Firebase AI Logic の大事ポイントはここ👇

  • アプリ → Firebase AI Logic の プロキシ(中継) を通って Gemini / Imagen に行く🚪
  • そのプロキシで App Check トークンを検証できる🧿✅
  • 特に Gemini Developer API を使う場合、Gemini API key をアプリに埋め込まない運用が超重要(キーはバックエンド側で使われる)🔐 そして “本気で作り始めたら App Check 統合がクリティカル” とはっきり書かれてます。(Firebase)

さらに、Firebase AI Logic は App Check / Remote Config / AI monitoring に対応と明記されています。(Firebase)


3) 守りの基本セットは3つ🧰🧿

Three Tools

A. App Check(必須)🧿

AI Logic のプロキシが App Check を検証できるので、正規アプリだけ通すができます。(Firebase)

B. “limited-use” App Check トークン(強め)⏱️🧿

AI呼び出しみたいな「コスト高い・悪用されやすい」場面では、短命の limited-use トークンが推奨されています(TTL 5分)。(Firebase) ただし 追加の通信が増えるので、全部に常時ONというより「AIだけON」が現実的👍(Firebase)

C. レート制限(Quota)💥🚦

Firebase AI Logic API には “1ユーザーあたり/1分あたり” の上限があり、デフォルトは 100 requests/min/user と書かれています。(Firebase) 超えると 429(Quota exceeded) になります。(Firebase) そして重要:特定ユーザーだけ別上限みたいなのは(少なくとも現時点では)できない、という注意もあります。(Firebase)


4) 手を動かす:AI整形ボタンを作る🧩⚛️🤖

4-1. まずは最小で “AI整形” 関数を作る🛠️

Secure Client Code

ポイントは👇

  • モデルは新しめを使う(古いのが退役予定だったりする)🧯 例として、公式ガイドは gemini-2.5-flash 系を普通に出してます。(Firebase)
  • 退役予定の注意:gemini-2.0-flash2026-03-31 に退役予定と書かれています(なので今から新規で選ぶ意味は薄い)。(Firebase)

例:src/lib/aiPolish.ts

import { getApp } from "firebase/app";
import { getAI, getGenerativeModel, GoogleAIBackend } from "firebase/ai";

/**
* メモを「読みやすく」整形する(要約+言い換え)
*/
export async function polishMemo(raw: string): Promise<string> {
const ai = getAI(getApp(), {
backend: new GoogleAIBackend(),
// AI呼び出しは“悪用されやすい”ので短命トークンを推奨(後述)
useLimitedUseAppCheckTokens: true,
});

const model = getGenerativeModel(ai, {
model: "gemini-2.5-flash",
});

const prompt = [
"あなたは文章の編集者です。",
"次のメモを、意味を変えずに読みやすく整形してください。",
"条件:",
"- 箇条書きOK",
"- 1〜2行の要約を先頭に付ける",
"- 口調は丁寧すぎず自然に",
"",
"メモ本文:",
raw,
].join("\n");

const result = await model.generateContent(prompt);
return result.response.text();
}

firebase/ai を使って getAIgetGenerativeModelgenerateContent() の流れは公式ガイドにも載っているパターンです。(Firebase)

💡 useLimitedUseAppCheckTokens: true は、AI Logic の App Check ガイドにある推奨オプションです(Web SDK v12.3.0+)。(Firebase)


4-2. React 側に「AI整形」ボタンを付ける⚛️🖱️

例:src/components/MemoPolishButton.tsx

import { useState } from "react";
import { polishMemo } from "../lib/aiPolish";

export function MemoPolishButton(props: {
value: string;
onApply: (next: string) => void;
}) {
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);

async function onClick() {
setLoading(true);
setError(null);

try {
const polished = await polishMemo(props.value);
props.onApply(polished);
} catch (e: any) {
// だいたいここに「App Check」か「Quota」か「ネットワーク」系が飛んでくる
const message =
typeof e?.message === "string" ? e.message : "AI整形に失敗しました";
setError(message);
} finally {
setLoading(false);
}
}

return (
<div>
<button disabled={loading} onClick={onClick}>
{loading ? "整形中…🤖" : "AIで整形✨"}
</button>

{error && (
<p style={{ marginTop: 8 }}>
⚠️ {error}
<br />
<small>(時間をおいて再実行、または再読み込みを試してね🙂)</small>
</p>
)}
</div>
);
}

5) ON/OFF比較で “守れてる感” を体感👀🧿

Verification Process

ここ、めちゃ大事です🔥 守りは「効いてるか確認」しないと、ただの気分になりがち😇

手順(おすすめ)

  1. Firebase Console で App Check を「監視(enforceしない)」状態にしておく👀

  2. AI整形ボタンを押して、普通に動くのを確認✅

  3. 次に、Console 側で AI Logic への enforcement をON(= 未検証を拒否)🧿🚫

  4. その状態で、わざと App Check 初期化を外したビルド(または別の未設定クライアント)から叩いてみる

    • ここで 失敗(拒否) すれば勝ち🎉

AI Logic は App Check 統合がサポートされていて、プロキシが App Check トークンを検証できる構成になっています。(Firebase)


6) レート制限(Quota)で “破産しない” を作る💸🚦

Rate Limiting

Firebase AI Logic API の quota は、ざっくりこう考えるとラク👇

  • 通常運用:1ユーザーあたり 100回/分 は多い(普通のアプリなら十分)

  • 事故るパターン

    • 無限連打ボタン
    • バグで自動リトライ地獄
    • 悪意あるスクリプト

公式ドキュメント上、デフォルトは 100 requests/min/user。(Firebase) また、クォータは RPM/RPD/TPM/TPD のどれか超過でもエラーになるよ、という説明もあります。(Firebase)

実運用のコツ🎛️

  • 最初は 控えめ(例:30〜60 rpm/user) にして様子見👀
  • 問題なければ上げる(逆はUX事故りやすい)🙂
  • 特定ユーザーだけ上げるは現状できない前提で設計(管理者だけ別枠にするなら、別経路/別バックエンドを検討)(Firebase)

7) “構造化出力(JSON)” を使うと事故が減る🧾🤖

Structured JSON

AIの戻りがただの文章だと👇が起きがち😵‍💫

  • JSONのつもりが崩れる
  • 余計な説明が混ざる
  • UI側のパースで死ぬ

Firebase AI Logic は responseMimeType と responseSchema で構造化出力を作れます。(Firebase)

例:整形結果を { summary, body } のJSONで返させる

import { getApp } from "firebase/app";
import { getAI, getGenerativeModel, GoogleAIBackend, Schema } from "firebase/ai";

export async function polishMemoAsJson(raw: string) {
const ai = getAI(getApp(), {
backend: new GoogleAIBackend(),
useLimitedUseAppCheckTokens: true,
});

const schema = Schema.object({
properties: {
summary: Schema.string(),
body: Schema.string(),
},
});

const model = getGenerativeModel(ai, {
model: "gemini-2.5-flash",
generationConfig: {
responseMimeType: "application/json",
responseSchema: schema,
},
});

const prompt = [
"次のメモを読みやすく整形してJSONで返して。",
"summary: 1〜2行の要約",
"body: 整形後本文(箇条書きOK)",
"",
raw,
].join("\n");

const result = await model.generateContent(prompt);
return result.response.text(); // JSON文字列(ここをJSON.parseしてUIへ)
}

この responseMimeType: "application/json"responseSchema の形は公式の例に沿っています。(Firebase)


8) AI monitoring で “異常の早期発見” 👀📈

AIは 「気づいた時には請求が…」 が起きがちなので、監視は保険です🧯💸

AI monitoring については👇が書かれています:

  • Web だと Firebase JS SDK v11.8.0+ が必要
  • データ収集の オプトイン設定が必要(Firebase)
  • さらに、観測(Cloud Observability)側のコストが発生しうる点にも注意、とあります(Firebase)

9) AIでAI実装を加速(Antigravity / Gemini CLI)🚀🤖

ここは “作業が早くなる” おまけコーナー🎁✨(でも超実戦的)

  • Antigravity:エージェントが計画〜実装まで進める思想の入門が公開されています。(Google Codelabs)
  • Gemini CLI:ターミナル統合のオープンソースAIエージェントとして紹介されています。(Google Cloud Documentation)
  • Firebase Studio:ワークスペース(環境再現)まわりの説明があります。(Firebase)

使い方の例(そのまま投げてOK)🗣️🤖

  • firebase/ai を使ってる場所を全検索して、useLimitedUseAppCheckTokens が必要な箇所を提案して」🔎
  • 「AIボタンが連打された時に、UIで“クールダウン”する実装案を出して」🧊
  • 「429の時のUX文言を3案、優しめで」🙂

ミニ課題🎯✨

次の3つをやったら、この章は “勝ち” です🏆

  1. ✅ AI整形ボタンが動く(最低1回成功)🤖
  2. ✅ App Check enforcement をONにして、未検証リクエストが落ちるのを確認🧿🚫
  3. ✅ Quota を「自分のアプリに合う値」に調整して、429時の表示も作る💸🚦

チェック✅(理解できたらOK)

  • ✅ 「AIはコストが読みにくいから、App Check+Quotaで守る」が言える🙂
  • ✅ limited-use トークンは “AIみたいな高コストAPIに寄せる” のが納得できる⏱️🧿(Firebase)
  • ✅ 429(Quota)と 403系(App Check/認可っぽい)を UIで分けて扱うイメージがある🚦🧯

次の章(第13章)は Debug Provider で「ローカル開発が詰まらない」ようにするやつです🧪🧿 でも先に、あなたのプロジェクト構成に合わせて「AI整形ボタンの置き場所(services層/hooks化)」を最適化する版も作れますよ⚛️✨