Flutter应用中Firestore规则导致书签子集合创建权限被拒
问题解决:Firestore权限拒绝与书签创建失败
核心问题定位
报错信息里的Query(Bookmarks order by __name__)明确指向:你的代码直接访问了根级Bookmarks集合,但当前Firebase规则完全未配置该根集合的访问权限,因此触发Permission Denied。更关键的是,你的业务逻辑是检查当前用户的书签是否重名,根本不需要访问根级Bookmarks,应该查询用户专属的Users/{uid}/Bookmarks集合。
步骤1:修正Flutter代码中的查询逻辑
把根集合查询替换为用户专属书签集合查询,同时修复原重名检查的逻辑漏洞(原循环会覆盖nodup值,仅最后一个文档的判断生效):
void _submit() async { setState(() => _submitted = true); if (_errorText == null) { final user = FirebaseAuth.instance.currentUser!; // 修正:查询当前用户自己的Bookmarks集合,而非根级Bookmarks final querySnapshot = await FirebaseFirestore.instance .collection('Users') .doc(user.uid) .collection('Bookmarks') .get(); // 优化重名检查:直接判断是否存在同名书签 bool nodup = !querySnapshot.docs.any((doc) => doc.data()['collectionName'] == _controller.text.trim()); } // Important Part if (nodup) { final bookmarkRef = await FirebaseFirestore.instance .collection('Users') .doc(user.uid) .collection('Bookmarks') .add({'collectionName': _controller.text.toString()}); await FirebaseFirestore.instance .collection('Users') .doc(user.uid) .collection('Bookmarks') .doc(bookmarkRef.id) .collection(_controller.text.toString()) .add({ 'key': widget.keyo, 'productName': widget.name, 'color': widget.color.toString() }); if (mounted) { Fluttertoast.showToast( msg: "Product added to the Collection", toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, timeInSecForIosWeb: 1, backgroundColor: const Color(0xfff1f7f3), textColor: AppTheme.signAppColor, fontSize: 14, ); } } if (mounted) Navigator.of(context).pop(); }
步骤2:优化Firebase安全规则
原规则中/Users/{userId}的create权限过于宽松(任何登录用户都能创建其他用户的文档),同时简化书签层级的权限配置,确保只有用户本人能操作自己的数据:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /Users/{userId} { // 仅用户本人能创建、更新、删除自己的用户文档,所有登录用户可读取 allow read: if request.auth != null; allow create, update, delete: if request.auth != null && request.auth.uid == userId; match /Bookmarks/{bookmarkId} { // 用户本人可操作自己的书签文档及所有子集合 allow read, write, create, delete: if request.auth != null && request.auth.uid == userId; match /{document=**} { allow read, write, create, delete: if request.auth != null && request.auth.uid == userId; } } } } }
验证逻辑
- 重名检查仅查询当前用户的书签集合,不再越权访问根集合
- 书签创建流程完全在用户专属的
Users/{uid}/Bookmarks层级下,符合安全规则权限要求 - 优化后的规则修复了原规则的安全漏洞,确保用户只能操作自己的数据
内容的提问来源于stack exchange,提问作者ItsHarsh.json
相关产品推荐
相关产品推荐

