firebase_storage_ts_study_016
第16章:Rulesで「画像だけ&サイズ上限」を強制する🧯🛡️
この章は「アップロード前チェック(第7章)」だけに頼らず、最後の門番=Storage Rulesで「画像以外&デカすぎ」をガチで弾く回だよ〜📷🚫 (2026-02-03更新の公式ドキュメント内容で確認して組み立ててるよ✅) (Firebase)

1) まず“腹落ち”させたいこと🍞🧠

✅ Rulesができること(この章の主役)
Storage Rulesは、ファイルのメタデータを見てチェックできるよ👇
request.resource.size:アップロードされるファイルのサイズ(バイト)📏request.resource.contentType:MIMEタイプ(例:image/jpeg)🏷️ そしてmatches()を使って「image/.*だけ」みたいな制限が書ける✨ (Firebase)

✅ “request.resource” と “resource” の違い🔍
超重要!ここで事故が減るよ🔥
resource:すでに存在してるファイルのメタデータ(既存)📦request.resource:これから書き込まれるメタデータ(新規/更新)🆕📦 「書き込み時は両方使える」って公式でも説明されてるよ。 (Firebase)

⚠️ つまずきポイント(先に潰す)💥
- 「
allow writeに size / contentType を入れたら、削除が通らなくなった😇」 →writeは “create/update/delete” をまとめた操作。操作ごとに分けると安全だよ(次でやる)🧯 (Firebase) - 「
image/*ならOKでしょ?」 →image/svg+xmlみたいに扱いが難しいものもあるから、PNG/JPEG/WebPだけ許可みたいに狭めるのが安心なことが多いよ🧷
2) 手を動かす✋💻(Rulesを“運用っぽく”書く)
ここでは「プロフィール画像」想定で👇
- パス:
users/{uid}/profile/{fileId}📁 - 上限:例として 2MB(好きに変えてOK)🧃
- 許可:JPEG / PNG / WebPのみ✅

手順A:まず“運用版”のRulesを用意する🧩
ポイントはこれ👇
writeでまとめず、create / update / delete に分ける🧯 (Firebase)- create で「サイズ」「contentType」をチェック
- update では「contentTypeを変えられない」も入れる(地味に効く)🧷 (Firebase)
rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
// プロフィール画像置き場
match /users/{uid}/profile/{fileId} {
// 共通:ログインしてて本人
function isOwner() {
return request.auth != null && request.auth.uid == uid;
}
// 共通:許可する画像形式(SVGはあえて除外)
function isAllowedImageType() {
return request.resource.contentType.matches('image/(jpeg|png|webp)');
}
// 共通:サイズ上限(例: 2MB)
function isUnderLimit() {
return request.resource.size < 2 * 1024 * 1024;
}
// 読み取り:本人だけ(公開にしたいならここを調整)
allow read: if isOwner();
// ✅ 新規アップロード:画像形式 + サイズ制限
allow create: if isOwner()
&& isUnderLimit()
&& isAllowedImageType();
// ✅ メタデータ更新:本人 + contentType変更禁止(すり替え防止)
// ※ update は「既存ファイルのメタデータ更新」に対して効くよ
allow update: if isOwner()
&& resource != null
&& request.resource.contentType == resource.contentType;
// 🗑️ 削除:本人だけ(“使用中は削除不可”は第13章の設計と合体でやる)
allow delete: if isOwner();
}
}
}
公式でも
sizeとcontentTypeで「5MB未満の画像だけ」みたいな検証ができる例が載ってるよ(考え方は同じ)📚 (Firebase) さらにrequest.resourceとresourceを使い分けて、形式すり替えを防ぐ例もあるよ🛡️ (Firebase)
手順B:反映(コンソールでもCLIでもOK)🚀
① コンソールで反映(サクッと)🧑💻
Firebase console → Storage → Rules → さっきのRules貼る → 公開(Publish)✅ (ミスっても戻せるから怖がらなくてOK🙂)
② CLIで反映(おすすめ:Git管理できる)🧰
PowerShellでこんな感じ👇
# Firebase CLI(入ってなければ)
npm i -g firebase-tools
firebase login
firebase init storage
firebase deploy --only storage
手順C:テスト(わざと失敗させるのがコツ)🧪💥
✅ 成功ケース
me.jpg(500KB)をアップロード → 通る🙆♀️
❌ 失敗ケース(期待通り弾けたら勝ち)
- 3MBの画像 → サイズ超過で拒否🙅♂️
.txtをアップロード(contentTypeがtext/plainになりがち)→ 形式で拒否🙅♀️- 他人の
users/{uid}に突っ込む → 本人一致で拒否🙅

3) AIを絡めて“強いRules”を最速で作る🤖⚡
✅ Gemini in Firebase:相談・原因究明に強い🧯
Rulesのエラー原因や考え方を聞くのに便利! ただし コンソールのGeminiはコードベースを見れないので、Rulesを生成する用途はGemini CLIなどが推奨って公式にも明記されてるよ。 (Firebase)
✅ Gemini CLI / Antigravity:Rulesの“生成・改修・レビュー”に強い🛠️
Firebaseの MCP server は、Antigravity / Gemini CLI / Firebase Studio などから使えるって公式に書かれてる!めっちゃ相性いいやつ🚀 (Firebase)
そのまま使えるプロンプト例✍️✨
(Gemini CLI / Antigravity のチャットに投げる用)
目的:プロフィール画像アップロードのStorage Rulesを安全にしたい。
要件:
- パスは users/{uid}/profile/{fileId}
- 読み取りは本人のみ
- 書き込みは本人のみ
- create は JPEG/PNG/WebP のみ許可
- サイズは 2MB 未満
- update で contentType のすり替えを防ぎたい
- delete は本人のみ
上の要件を満たす rules_version=2 のルールを提案して。
さらに「ありがちな穴」「テストケース(成功/失敗)」も10個出して。
さらに一歩:Gemini CLIのFirebase拡張で“雛形生成”🧩
公式のプロンプトカタログでは、**Gemini CLI拡張は1回実行でRulesを生成する(自動追従はしない)**って注意もあるよ。つまり、作った後の更新は自分でやる方式📝 (Firebase)
4) ミニ課題🎯📌
ミニ課題A:許可する画像形式を増やす🧪
今は jpeg|png|webp。
ここに「gif を追加」してみてね(ただしプロフィールでGIFを許すかは好み!)😄
ミニ課題B:上限を“プロダクトっぽく”決める💡
- アイコンだけなら 512KB〜1MB でも十分なこと多い
- 高画質を許すなら 2MB〜5MB 「なぜその数値か」を一言で言えるようにしよ🗣️✨

5) チェック✅✅✅
request.resource.sizeとrequest.resource.contentTypeで弾ける理由を説明できる📏🏷️ (Firebase)request.resourceとresourceの違いが言える🧠 (Firebase)writeをcreate/update/deleteに分ける意味がわかる🧯 (Firebase)- 失敗テスト(サイズ超過/形式違い/他人パス)が全部ちゃんと拒否される🙅♂️💥
- AI(Gemini in Firebase / Gemini CLI / Antigravity)で「レビュー→修正→再テスト」が回せる🤖🔁 (Firebase)
次の章(第17章)は App Checkで“正規アプリ以外”を通しにくくする から、ここで作ったRulesがさらに頼もしくなるよ🧿✨