🔐
Firestoreのセキュリティルールでフィールドの値を利用する【Firebase】
🔥 導入
とあるアプリプロジェクトでfirestoreのセキュリティルールを設定していたのですが、
その際にドキュメント内のフィールドの値によって権限を変更する、という仕様がありました。
その時に調べたことのメモ。
特にフィールドがReference型である場合の扱いで沼ったので、その備忘録として。
🔍 対象
- Firestoreのセキュリティルールの基本的な書き方がわかる
- Firesotreのセキュリティルールで、ドキュメントのフィールドの値を利用したい
✅ 結論
フィールドの値は以下のように使います。
// String型を利用
allow write: if resource.data.name == 'Alice';
// int型を利用
allow write: if resource.data.number > 5;
// bool型を利用
allow write: if resource.data.isDelete == false;
// Reference型を利用
allow write: if get(resource.data.docRef).id == request.auth.uid;
🧐 resourceとrequest.resourceの違いについて
ドキュメントのフィールドを利用する際、
resourceとrequest.resourceが利用できます。
| プロパティ | 役割 | 使用シーン |
|---|---|---|
| resource | 現在Firestoreに保存されているデータ | 既存のドキュメントのデータを確認するとき |
| request.resource | リクエストされた(更新・作成しようとしている)データ | 新しく書き込むデータを検証するとき |
使い分け
| ケース | resource | request.resource |
|---|---|---|
| 読み取るデータ | 既にFirestoreに保存されているデータ | ユーザーが送信しようとしているデータ |
| いつ使うか |
readやupdateの前のデータチェック |
createやupdateの新しいデータの検証 |
| 使える操作 |
read, update, delete
|
create, update
|
⚠️ Reference型の扱いに注意
フィールドの値は基本的にそのまま利用できます。
公式ドキュメントにも記載があります。
Stiring型やint型はそのまま利用していますね。
抜粋1
match /cities/{city} {
allow read: if resource.data.visibility == 'public';
}
抜粋2
match /cities/{city} {
allow update: if request.resource.data.population > 0
&& request.resource.data.name == resource.data.name;
}
そのため、私はReference型も以下のようにして利用しようとしたのですが...なぜかパーミッションエラーが出る。
以下の例の前提
トップレベルコレクションとして、userコレクションと、postコレクションがあり
postドキュメントには、誰が投稿したのものかがわかるように、userコレクションへの参照を保存するcreateuserRefフィールドがあると仮定。
├── user/
│ ├── {userID}/
│ │ ├── name: String
│ │ ├── age: int
├── post/
│ ├── {postId}/
│ │ ├── createuserRef: Reference
│ │ ├── contentText: stirng
│ │ ├── createdAt: timestamp
match /post/{postId} {
allow update: if request.resource.createuserRef.id == request.auth.id;
}
Reference型はgetする!
Reference型を利用する際は必ずgetしましょう!!
match /post/{postId} {
allow update: if get(request.resource.createuserRef).id == request.auth.id;
}
ちなみにReference型として利用できるので、、、
get(request.resource.createuserRef).pathを使えるようです。
🔖 最後に
Firestoreのセキュリティルールをしっかりと設定して、より良いアプリライフを!
間違えている部分等あったらご教授いただけると幸いです!!
Discussion