Firestoreで「Missing or insufficient permissions」が出たとき、Security Rulesを全許可へ広げたり、認証設定を変えたりする前に、失敗した要求がどのAPI経路を通り、どのproject・database・document pathに対して、どの認証状態とqueryで実行されたかを分けてください。Web・Android・iOSなどのFirestore client SDKはSecurity Rulesで評価されます。一方、Admin SDKなどのserver client libraryはRulesを通らず、IAMで認可されます。最初の分岐を誤ると、Rulesを直しても症状が変わらないことがあります。
このエラーの原因は、少なくとも「request.authが想定と違う」「match pathが実際のdocument pathと一致しない」「queryがRulesの許可条件を保証しない」「実行先project/databaseや適用中のRulesが想定と違う」に分かれます。まず失敗した操作の記録を作り、該当する枝だけを確認します。この記事は一般的な診断手順です。特定のFirebase projectを調べたり、Rules変更を実行したりした結果ではありません。
目次
まず失敗した要求を一行で記録する
ブラウザconsoleやアプリログから、失敗した操作を次の形に整理します。access token、refresh token、秘密鍵、ユーザーの個人情報は記録へ貼らないでください。uidやproject IDが必要なら、共有範囲を限定した記録にします。
表は横にスクロールできます
| 記録項目 | 確認する値 | ここで分かること |
|---|---|---|
| SDK / API | Web・Android・iOS client SDK、Admin SDK、REST/RPCなど | Rulesを調べるかIAMを調べるか |
| 操作 | get、list/query、create、update、delete | 読み取り・一覧・書き込みのどの条件か |
| 実行先 | Firebase project ID、database ID、emulatorか実環境か | 想定した設定を見ているか |
| パス | collection / document path | Rulesのmatchと一致するか |
| 認証状態 | 未ログインか、ログイン済みか、想定uidか | request.authの条件を満たすか |
| query条件 | where、orderBy、limitなど | Rulesが許可する結果集合を保証するか |
| 適用中のRules | 実際にデプロイ済みのRulesと版 | ローカル編集内容と実行先が一致するか |
「ユーザーはログインしている」といった画面上の状態だけでは十分ではありません。Firestoreへの要求時点で、そのSDK instanceが期待するFirebase projectへ接続され、期待するユーザーの認証状態を持っているかを確認します。ログイン成功後に別のFirebase app instanceを使っている、ログアウト直後の古い画面が残っている、認証listenerの初期化前にqueryを実行した、という可能性はアプリ側で確認してください。特定アプリでこれらが原因だとは断定できません。
Rulesを調べる前にclient SDKかserver SDKかを分ける
最初にFirestoreへの経路を特定します。
表は横にスクロールできます
| 経路 | 主な認可の確認先 | よくある確認 |
|---|---|---|
| Web / Android / iOSのFirestore client SDK | Cloud Firestore Security RulesとFirebase Authentication | request.auth、match path、Rules条件、query |
| Admin SDKなどserver client library | Google Cloud IAM / service account | 実行principal、IAM role、project、credential |
| REST / RPC | APIの認証方式とIAMなど、その経路の公式認可条件 | client SDK Rulesが適用されると決めつけない |
Cloud Firestoreの公式資料では、server client libraryはSecurity Rulesを迂回し、Google Application Default Credentials等で認証してIAMを使うと説明されています。そのため、サーバー側処理の失敗に対して、client用Rulesへ条件を足すのは原因と違う場合があります。どのSDKか確信が持てない場合は、依存パッケージ、初期化コード、実行環境、credentialの種類を確認してから調査先を決めます。credentialそのものをログへ出す必要はありません。
client SDKならrequest.authとRulesのmatchを照合する
client SDKの要求では、まず認証条件とpath条件を別々に見ます。Firebase Authenticationでユーザーが認証されていれば、Rules内のrequest.authにはその認証情報が渡されます。未認証状態ではrequest.authはnullです。ただし、認証済みであることだけでFirestoreのread/writeが許可されるわけではありません。Rulesのallow条件も満たす必要があります。
次に、コードが実際に参照するdocument pathとRulesのmatchを照合します。例えば、コードが /accounts//orders/ を読むなら、Rulesが /users//orders/ だけに適用される状態では一致しません。collection group queryを使う場合は、通常のcollection queryと同じpath想定でよいとは限らず、collection group向けのRules scopeを公式仕様に沿って確認します。pathの大文字小文字、collection名、database ID、ネスト階層も並べて確認してください。
読み取りも単一documentのgetとcollectionのlist/queryを分けてください。単一document readは特定のdocumentを対象にRules評価されます。queryは候補集合全体を対象にするため、単一document readが成功することだけではcollection queryの許可を証明しません。書き込みでは、作成前のresourceと作成後のrequest.resourceをどちらの条件に使っているか、更新対象のpathが同じかも確認します。
queryはRulesに許可された結果集合を保証する必要がある
Firestore Security Rulesは結果を後から絞り込むfilterではありません。queryが返し得るdocumentの中に、Rulesで拒否されるものが含まれる可能性があれば、実際のデータ上で拒否対象が見つからなくても、query全体が拒否されることがあります。queryの制約は、Rulesの条件が許す範囲を保証しなければなりません。
表は横にスクロールできます
| Rulesの考え方 | query側で照合すること |
|---|---|
| 所有者uidが一致するdocumentだけread可能 | queryにも同じuid条件があるか |
| publishedがtrueのdocumentを公開read可能 | queryでpublished == trueを保証しているか |
| listには最大件数が必要 | queryにRulesが認めるlimitがあるか |
| OR / in / array-contains-anyの各候補を条件で評価 | 各候補値がすべてRules条件を満たすか |
| collection groupを許可する条件 | collection group queryのpathとRules version / matchが合うか |
例えばRulesが「resource.data.ownerUid == request.auth.uid」のdocumentだけを許可するなら、collection全体を読むqueryでは他ユーザーのdocumentが結果に含まれる可能性を排除できません。ログイン中ユーザーの所有データだけを読むqueryへ制約を加える必要があります。この例は公式説明を簡略化した概念例で、特定のスキーマやコードに対する実装指示ではありません。field名やquery APIは実際のデータモデルに合わせてください。
まずRulesのread/list条件から必要なquery条件を抜き出し、次に実際のqueryを横に並べます。field名だけでなく、演算子、値、OR条件、limit、collection scopeを比較します。インデックス不足は通常別のエラーとして表れるため、このpermission errorを見ただけでインデックスを原因と決めつけず、実際のエラーとSDKログを確認します。
project・database・Rulesの反映先を確認する
アプリが意図したFirebase projectとFirestore databaseへ接続しているかを確認します。開発・staging・productionでFirebase configや環境変数が異なる場合、別projectに要求している可能性があります。複数databaseを使う構成ではdatabase IDも記録してください。emulator利用時には、SDKが実際にemulator hostへ接続しているか、予期せず実環境へ接続していないかも確認します。
次に、手元で編集しているRulesと、失敗が起きたprojectへ反映されているRulesを比べます。ローカルファイルが正しくても、デプロイ先や公開済みRulesが別なら実際の評価は変わりません。ConsoleまたはFirebase CLIで対象project、database、Rules内容、反映日時を確認します。Production Rulesの変更は利用者全体のアクセスに影響するので、原因未確定のまま全許可へ変更したり、広いmatchを足したりしないでください。
安全なRulesテストを組み立てる
本番データや本番Rulesを直接緩める前に、Firebase Local Emulator SuiteとSecurity Rules unit testingを使って、許可・拒否の両方を再現します。公式のRules unit testingライブラリは、未認証・認証済みcontextを分けたtestを作り、テスト用認証状態でRulesの挙動を確認する用途です。テストには、実際のRulesファイルが読み込まれていること、demo用または隔離されたproject IDを使っていること、Firestore emulatorへ接続していることを含めます。
表は横にスクロールできます
| テスト | 期待する結果を決める前提 |
|---|---|
| 未認証client | 公開readを許すのか、認証を要求するのか |
| 認証済み本人 | uid / role / document field条件を満たすか |
| 別ユーザー | 他人のdocumentを拒否できるか |
| query条件あり | Rulesの条件が結果集合全体で成立するか |
| query条件なし | 拒否されるべき要求を拒否するか |
| 書き込み | create / update / deleteで必要なfieldやpathを確認するか |
上表はテストケースを設計するためのチェックリストであり、現行projectに対する合否結果ではありません。EmulatorにRulesファイルを読み込まないと、公式資料の注意どおり初期状態でopen rulesとして扱われる可能性があります。テストが通ったことだけでProductionのRules反映まで確認済みとは言えません。テスト対象のRulesとproject設定が正しいことを確認し、結果と対象revisionを一緒に記録します。
調査結果から次の修正を選ぶ
原因が分かったら、変更対象を絞ります。
表は横にスクロールできます
| 確認結果 | 次に行うこと | 避けること |
|---|---|---|
| request.authがnull / uidが違う | client初期化、ログイン状態、要求時点を確認 | 全read/writeをpublicにする |
| document pathとmatchが違う | コードのpathとRulesのmatchを修正対象として比較 | 意味を確認せず広いwildcardを追加 |
| queryがRulesの条件を保証しない | Rulesに合うquery条件か、データ設計を検討 | query結果の実データだけを見て通ると判断 |
| server SDK / RESTのIAM経路 | 実行principalと対象resourceのIAMを確認 | client Security Rulesだけを編集 |
| project / database / emulatorが違う | configと実際の接続先を照合 | 本番設定を推測で差し替え |
| 適用中Rulesが古い | 変更履歴とデプロイ対象を確認し、適用方法を計画 | 原因が分かる前にProduction反映 |
本番Rulesを変える必要がある場合は、意図した利用者だけを許可する条件を保ち、最小差分で行います。アクセス範囲が広がる変更は、コードだけで自己判断せず、データの機密性と利用者への影響を確認してください。テストで「拒否されるべきケース」が通ってしまったなら、成功と数えず、ルールの緩和を戻して原因を調べます。
再発を減らす確認記録
permission-deniedを再発時に比較できるよう、次の情報を安全な範囲で残します。
-
Error全文からcredentialや個人情報を除いたもの
-
client SDK / server SDK / REST等の経路
-
操作種別、collection/document path、projectとdatabase
-
request時点の認証状態と、Rulesで参照するuid / role
-
query条件一式とRulesの対応するallow条件
-
Emulatorまたは実環境の別、適用中Rulesの確認日時
-
allowされるケースとdenyされるケースのtest結果
-
未確認の前提と、次に確認する担当・場所
原因が特定できなければ、広いアクセスを追加して先へ進めるのではなく、再現に必要な最小情報を揃えて管理者またはFirebase担当者へ渡します。Rulesの条件とqueryの関係を説明できる状態になってから修正を依頼してください。
まとめ:まずSDK経路と失敗したqueryを特定する
Web / Android / iOS client SDKなら、request.auth、document path、Rulesのallow条件、queryのpotential result、実際に適用されたRulesを順に照合します。Admin SDK等のserver経路ならIAMを調べます。実projectやRulesの内容が確認できない限り、原因を断定せず、全許可ルールも本番へ出しません。次は、失敗ログから操作種別・接続先・path・認証状態・query条件を記録し、該当する分岐をEmulatorで再現してください。
参考情報
-
Firebase, Securely query data (Cloud Firestore Security Rules): https://firebase.google.com/docs/firestore/security/rules-query(新しいタブで開く) (確認日:2026-10-15)
-
Firebase, Test your Cloud Firestore Security Rules: https://firebase.google.com/docs/firestore/security/test-rules-emulator(新しいタブで開く) (確認日:2026-10-15)
-
Firebase, Writing conditions for Security Rules: https://firebase.google.com/docs/firestore/security/rules-conditions(新しいタブで開く) (確認日:2026-10-15)
-
Firebase, Structuring Security Rules: https://firebase.google.com/docs/firestore/security/rules-structure(新しいタブで開く) (確認日:2026-10-15)
-
Firebase, Connect your app to the Cloud Firestore Emulator: https://firebase.google.com/docs/emulator-suite/connect_firestore(新しいタブで開く) (確認日:2026-10-15)
