Firestore规则模拟器空值错误:添加formID条件后触发问题
解决Firestore规则模拟器中的空值错误
问题原因
空值错误的核心是当请求未携带身份验证信息(request.auth为null)时,直接访问request.auth.uid。
你添加resource.data.formID == 'exampleFormID'的测试规则后,若在模拟器中测试未登录的请求,规则会依次检查所有||连接的条件。当执行到isDocumentOwner函数时,因request.auth为null,访问request.auth.uid就会触发空值错误。
修复方案
方案1:修改isDocumentOwner函数,增加身份验证存在性检查
在函数中先判断request.auth是否存在,再访问uid:
function isDocumentOwner(request, resource) { return request.auth != null && request.auth.uid == resource.data.ownerID; }
方案2:调整read规则的条件顺序
利用Firestore规则的短路求值特性,把不需要身份验证的formID判断放在最前面。当该条件满足时,后面依赖auth的条件不会被执行,避免空值错误:
allow read: if resource.data.formID == 'exampleFormID' || isDocumentOwner(request, resource) || isMember(request, siteID) || isAdmin(request);
方案3:给需要auth的条件统一加前置检查
如果要确保所有依赖request.auth的条件都不会在未登录时执行,可给这些条件加上request.auth != null的前置判断:
allow read: if resource.data.formID == 'exampleFormID' || (request.auth != null && (isDocumentOwner(request, resource) || isMember(request, siteID) || isAdmin(request)));
完整修改后的规则示例(以方案1为例)
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // 默认禁止所有读写 match /{document=**} { allow read, write: if false; } match /websites/{siteID} { allow get; allow list: if request.auth.uid in resource.data.memberList || isAdmin(request); allow write: if isAdmin(request); match /submissions/{submissionID} { allow create; allow read: if isDocumentOwner(request, resource) || isMember(request, siteID) || isAdmin(request) || resource.data.formID == 'exampleFormID'; allow update, delete: if isDocumentOwner(request, resource) || isAdmin(request); } } // 可复用规则函数 function isDocumentOwner(request, resource) { return request.auth != null && request.auth.uid == resource.data.ownerID; } // 其他函数... } }
内容的提问来源于stack exchange,提问作者andrilla
相关产品推荐
相关产品推荐

