Cloud Firestore 和 Realtime Database 都依赖于强大、简洁的规则语言,这些语言专用于管理信息安全和访问权限控制。但是,随着规则变得更长更复杂,您可能需要一些帮助来调试其行为中的错误。
Firebase 模拟器包括生成规则覆盖率报告的功能,因此您在重现错误时可以看到每个子表达式的确切评估结果。报告还提供有关每个测试用例使用规则的频率的信息,如传统的“线路覆盖”技术。
生成报告
运行一系列测试后,您可以访问测试范围报告,其中显示了每条安全规则的评估方式。
如需获取该报告,请在模拟器运行时查询其上的公开端点。如需适用于浏览器的版本,请使用以下网址:
Cloud Firestore
http://localhost:8080/emulator/v1/projects/<database_name>:ruleCoverage.html
Realtime Database
http://localhost:9000/.inspect/coverage?ns=<database_name>
这会将您的规则分解为表达式和子表达式,您可以将鼠标悬停在相应表达式上以了解更多信息(包括评估次数和返回的值)。如需这些数据的原始 JSON 版本,请在查询中包含以下网址:
Cloud Firestore
http://localhost:8080/emulator/v1/projects/<database_name>:ruleCoverage
Realtime Database
http://localhost:9000/.inspect/coverage.json?ns=<database_name>
调试示例规则
为了轻松生成测试报告,请使用 GitHub 提供的针对 Cloud Firestore 和 Realtime Database 的模拟器快速入门。 这些快速入门可指导您正确安装和初始化模拟器,然后从一组示例规则中生成示例测试。
假设有一个使用 Cloud Firestore 的示例应用,该应用计算用户点击按钮的次数。该应用采用以下规则:
Cloud Firestore
service cloud.firestore { match /databases/{database}/documents { match /counters/{counter} { allow read; allow write: if request.resource.data.value == resource.data.value +1; } } }
要调试上面显示的规则中的错误,请使用以下示例 JavaScript 测试:
const counter0 = db.collection("counters").doc("0");
await firebase.assertSucceeds(counter0.set({value: 0}));
模拟器生成上述网址中提供的报告:
http://localhost:8080/emulator/v1/projects/<database_name>:ruleCoverage.html
该报告显示以下未定义及空值错误:
此特定示例的问题在于规则不区分创建文档和更新文档。因此,如果文档不存在则不允许写入,那么文档不存在时也就无法创建文档。将“写入”区分为两个更具体的操作 -“创建”和“更新”,即可解决问题。
Cloud Firestore
service cloud.firestore { match /databases/{database}/documents { match /counters/{counter} { allow read; allow create: if request.resource.data.value == 0; allow update: if request.resource.data.value == resource.data.value +1; } } }
生成的报告显示每个规则的使用频率和返回的内容。