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
相关产品推荐
相关产品推荐

