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

Firestore多where查询实现链接资源可见性与所有权访问控制求助

问题解答

1. 合并查询报错原因

  • get() 方法返回的是 Promise 异步对象,直接用 + 拼接会触发隐式类型转换,将两个对象转为字符串拼接,最终得到的是普通字符串而非可调用 then 的 Promise 实例,需要使用 Promise.all() 批量处理多个异步请求。
  • 代码存在拼写错误:过滤条件中的字段名写为了 visibilty,少了一个字母 i,正确字段名为 visibility,会导致公开链接查询无返回结果。

2. 修复后的查询代码

需要先判断用户登录状态,未登录用户按照需求不能查看任何内容,同时对两个查询的结果做去重处理,避免用户自己的公开链接被重复加入列表:

const [links, setLinks] = useState([]);
useEffect(()=>{
    // 未登录时不返回任何链接
    if (!currentUser) {
        setLinks([]);
        return;
    }

    const fetchLinks = async () => {
        const linkMap = new Map(); // 基于id自动去重
        // 并行执行两个查询,等待全部返回
        const [publicSnapshot, ownerSnapshot] = await Promise.all([
            firebase.collection('links').where("visibility","==","public").get(),
            firebase.collection('links').where("created_by","==",currentUser.uid).get()
        ]);
        // 合并公开链接
        publicSnapshot.docs.forEach(doc => {
            linkMap.set(doc.id, {...doc.data(), id: doc.id});
        });
        // 合并个人所有提交的链接
        ownerSnapshot.docs.forEach(doc => {
            linkMap.set(doc.id, {...doc.data(), id: doc.id});
        });
        // 转数组更新状态
        setLinks(Array.from(linkMap.values()));
    }

    fetchLinks();
}, [currentUser]) // 依赖项添加currentUser,登录状态变化时自动重新拉取

3. 完善后的安全规则

原有规则未限制未登录用户查看公开链接,不符合需求,修改后规则如下:

match /links/{link}{
  allow create: if request.auth.uid != null;
  // 仅登录用户可查看公开链接,所有者可查看自己提交的所有链接
  allow read: if (resource.data.visibility == 'public' && request.auth != null) || resource.data.created_by == request.auth.uid;
}

内容的提问来源于stack exchange,提问作者user14709104

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 14:45:02