我正在开发一个具有以下数据结构的 Firestore 项目:
{
id: '12345',
title: 'Example List',
owner: ['user1', 'user2']
}
{
id: '67890',
title: 'Example Item',
listId: '12345',
toSchedule: true
}
每个项目都属于一个列表,并通过
listId
字段链接到该列表。列表由 ID 包含在 owner
数组中的用户拥有。我想设置 Firestore 安全规则以确保只有列表的所有者才能读取/写入/删除与该列表关联的项目。
这是我的安全规则设置:
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /lists/{listId} {
// Allow creation if the owner array contains the user's UID
allow create: if request.auth != null && request.resource.data.owner.hasAny([request.auth.uid]);
// Allow read, write, delete if the user is an owner
allow get, list, update, delete: if request.auth != null && request.auth.uid in resource.data.owner;
}
match /items/{itemId} {
function isOwnerOfList(listId) {
return get(/databases/$(database)/documents/lists/$(listId)).data.owner.hasAny([request.auth.uid]);
}
// Allow creation if the owner array contains the user's UID
allow create: if request.auth != null && request.resource.data.owner.hasAny([request.auth.uid]);
// Allow read, write, delete if the user is an owner of the associated list
allow get, list, update, delete: if isOwnerOfList(resource.data.listId);
}
}
}
这是我用来查询
items
集合的前端代码:
const Query = async (collectionName, additionalConditions = []) => {
const conditions = [...additionalConditions];
return onSnapshot(
query(collection(db, collectionName),
...conditions
),
snapshot => Snapshot(snapshot, collectionName, dispatch),
error => console.log('snapshot listener error', error)
)
}
Query('lists', [where('owner', 'array-contains', user)]) // This works
Query('items', [where('listId', '==', '_uNygDJjiwhdEoUPnZO_')]) // This works
Query('items', [where('toSchedule', '==', true)]) // This throws the insufficient permissions error
执行
Query('items', [where('toSchedule', '==', true)])
时,收到以下错误:Uncaught (in promise) FirebaseError: Missing or insufficient permissions.
owner
字段,因为列表可以与不同的人共享,从而允许他们拥有多个所有者。owner
文档中的lists
数组确实包含经过身份验证的用户的UID。items
集合设置安全规则有关,特别是与 isOwnerOfList
函数有关。我需要对 Firestore 安全规则或前端代码进行哪些更改,才能允许使用
items
等附加条件查询 where('toSchedule', '==', true)
集合而不会遇到权限错误?
谢谢您的帮助!
Query('items', [where('toSchedule', '==', true)])
不适用于您的安全规则,因为规则不是过滤器:“您无法在集合中编写查询(返回一些)文档并期望 Cloud Firestore 仅返回当前客户端有权访问的文档”.
您需要将此查询与
[where('owner', 'array-contains', user)]
查询结合起来。