FlutterFlow+Firebase安全规则配置问题:ListView无法读取数据
Firebase安全规则List权限问题解决方案
问题背景
用FlutterFlow+Firebase开发多企业应用,采用引用类型而非子集合管理数据:
- Companies:含name字段
- Offices:含name、ref_company字段
- Users:含name、ref_company、ref_office字段
- Data:含value、ref_company、ref_office、created_by字段
需求是登录用户可跨办公室操作本企业所有数据,当前CRUD操作正常,但ListView展示Data时出现权限错误:
Run mode-only notification: Firestore Security Rules Error on Container: Missing or insufficient permissions.
将allow list: if isSameCompany(resource.data);改为allow list: if isAuthenticated();可正常读取,但安全性过低。
问题原因
Firestore的List操作规则要求查询必须与规则逻辑匹配,仅检查单个文档的resource.data不够:
- 当执行List查询时,Firestore需要提前验证整个查询结果是否都符合权限,而非逐个检查文档。
- 原规则没有强制查询携带
ref_company过滤条件,Firestore无法确认查询范围,直接拒绝请求。
解决方案
1. 修改安全规则
更新List规则,强制查询必须包含ref_company等于用户所属公司的过滤,同时验证用户身份与文档权限:
function isAuthenticated() { return request.auth != null; } // 获取当前用户文档(添加空值判断避免报错) function getUserData() { let userDoc = get(/databases/$(database)/documents/users/$(request.auth.uid)); return userDoc.exists ? userDoc.data : null; } // 获取用户所属公司ID function getUserCompanyId() { let userData = getUserData(); return userData != null ? userData.ref_company : null; } // 验证文档所属公司与用户一致 function isSameCompany(resourceData) { let userCompany = getUserCompanyId(); return isAuthenticated() && userCompany != null && resourceData.ref_company != null && resourceData.ref_company == userCompany; } // 验证请求中的公司ID与用户一致 function isSameCompanyInRequest(requestData) { let userCompany = getUserCompanyId(); return isAuthenticated() && userCompany != null && requestData.ref_company != null && requestData.ref_company == userCompany; } // 验证查询是否包含正确的公司过滤 function queryMatchesCompany() { let userCompany = getUserCompanyId(); return isAuthenticated() && userCompany != null && request.query.where('ref_company', '==', userCompany); } match /data/{document} { allow get: if isSameCompany(resource.data); // List规则同时验证查询过滤和文档权限 allow list: if queryMatchesCompany() && isSameCompany(resource.data); allow create: if isSameCompanyInRequest(request.resource.data); allow update: if isSameCompany(resource.data) && isSameCompanyInRequest(request.resource.data); allow delete: if isSameCompany(resource.data); }
2. 配置FlutterFlow查询过滤
在ListView绑定的Data集合查询中,添加过滤条件:
- 字段选择
ref_company - 操作符选择
等于 - 值选择当前用户的
ref_company字段(FlutterFlow中可通过Current User变量获取)
说明
- 规则中的
queryMatchesCompany()确保查询只请求用户所属公司的数据,Firestore可提前验证查询合法性。 - 保留
isSameCompany(resource.data)作为双重验证,防止非法查询绕过过滤(比如手动构造不符合规则的查询)。 - 添加空值判断避免因用户文档不存在导致规则报错。
内容的提问来源于stack exchange,提问作者kenta_non_jp
相关产品推荐
相关产品推荐

