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

Firestore安全规则中exists()函数无法检测到已存在文档的问题

问题原因及解决方案

核心问题:测试中的异步操作未正确等待

你在测试代码中调用testUserDoc.set()时没有等待异步操作完成,导致后续执行assertSucceeds(testFollowersDoc.set(...))时,users/user1文档还未被写入到模拟Firestore中,安全规则里的exists()自然返回false。

修复步骤

  1. 确保用户文档创建完成后再执行后续操作
    在测试代码中添加await等待set()操作完成:

    const database = testEnv.authenticatedContext('user1').firestore();
    const testFollowersDoc = database.collection("followers").doc("user1");
    const testUserDoc = database.collection("users").doc("user1");
    
    // 等待用户文档创建完成
    await testUserDoc.set({about: "Wow", following: []});
    // 再执行followers文档的创建操作
    await assertSucceeds(testFollowersDoc.set({followers: []}));
    
  2. 验证安全规则逻辑(可选)
    你的安全规则逻辑本身是正确的,但可以再确认$(database)变量的引用——在Firestore安全规则中,$(database)会自动解析为当前数据库的名称,默认场景下无需修改。如果是多数据库场景,需要确保路径匹配,但你的场景中应该不存在这个问题。

  3. 测试断言的正确写法
    建议使用await直接调用assertSucceeds/assertFails,而不是通过expect(...).resolves,这样代码更直观且不易出错:

    // 测试无用户文档时创建失败
    await assertFails(testFollowersDoc.set({followers: []}));
    
    // 创建用户文档后测试成功
    await testUserDoc.set({about: "Wow", following: []});
    await assertSucceeds(testFollowersDoc.set({followers: []}));
    

额外注意事项

  • 使用@firebase/rules-unit-testing时,所有模拟Firestore的写入、读取操作都是异步的,必须通过await等待操作完成,否则模拟数据库的状态不会更新。
  • 可以在创建用户文档后,先执行一次读取操作验证文档存在,再测试followers的创建:
    const userDocSnapshot = await testUserDoc.get();
    console.log(userDocSnapshot.exists); // 应输出true
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 17:57:25