Firestore安全规则下JS SDK查询权限异常问题求助
解决Firestore安全规则查询权限错误问题
你的Firestore安全规则在单个文档读取时能正常返回数据,但查询操作返回空数组并触发权限错误,核心原因是查询规则无法通过get()逐个验证文档。Firestore要求查询规则必须是可快速评估的(依赖查询条件和索引),而不是动态读取每个文档的数据来判断权限。
原规则中的isBelongTo函数使用get()获取目标文档的users数组,这种方式仅适用于单个文档的get操作,无法支持批量查询:因为查询需要Firestore提前确定哪些文档符合权限,而不是逐个读取文档验证,否则性能会严重下降。
解决方案
修改安全规则
分别处理单个文档读取(get)和查询/列表读取(list),利用resource.data(当前文档数据)和查询条件匹配实现权限控制:
function isLoggedIn() { return request.auth != null; } // 验证查询是否包含正确的array-contains条件 function queryMatchesUser() { return request.query.where('users', 'array-contains', request.auth.uid); } match /accounts/{accountID}/{documents=**} { // 单个文档读取:验证当前用户uid在文档的users数组中 allow get: if isLoggedIn() && request.auth.uid in resource.data.users; // 查询操作:验证查询条件是筛选包含当前用户uid的文档 allow list: if isLoggedIn() && queryMatchesUser(); }
规则逻辑说明
- 对于
get操作(单个文档读取):直接通过resource.data.users获取当前文档的用户数组,验证用户uid是否在其中,无需额外读取文档,高效且符合规则要求。 - 对于
list操作(查询/列表读取):强制要求查询必须包含where('users', 'array-contains', request.auth.uid)的条件,确保Firestore可以通过索引快速筛选出用户有权限的文档,避免逐个验证。
修正SDK查询代码
确保查询时传入有效的uid,不要传空字符串(当用户未登录时应停止查询):
if (!uid) { // 处理未登录场景,比如提示用户登录 return; } onSnapshot(query(collection(db, "accounts"), where('users', 'array-contains', uid)), (querySnapshot) => { const docs = []; querySnapshot.forEach((doc) => { docs.push({ ...doc.data(), id: doc.id }); }); console.log(docs); });
内容的提问来源于stack exchange,提问作者Nguyễn Khánh Nguyễn
相关产品推荐
相关产品推荐

