You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
        }
      }
    }
  }
}

验证逻辑

  1. 重名检查仅查询当前用户的书签集合,不再越权访问根集合
  2. 书签创建流程完全在用户专属的Users/{uid}/Bookmarks层级下,符合安全规则权限要求
  3. 优化后的规则修复了原规则的安全漏洞,确保用户只能操作自己的数据

内容的提问来源于stack exchange,提问作者ItsHarsh.json

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 11:27:01