Firestore安全规则报错:调用get()时对象的id属性未定义
Firestore安全规则中引用类型访问
.id属性返回undefined的问题 错误信息
Error: simulator.rules 第[13]行,第[27]列。对象的id属性未定义。
安全规则代码
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { function isBusinessOwner() { let businessDocId = get(/databases/$(database)/documents/users/$(request.auth.uid)).data.managedBusinesses[0].id; let businessTeamUserId = get(/databases/$(database)/documents/businesses/$(businessDocId)).data.team[0].id; return request.auth.uid == businessTeamUserId; } match /businesses/{businessDocId} { allow read, write: if true; // Sub-collection: match /businessCustomerQueue/{queuedCustomerDocId} { allow read, write: if isBusinessOwner(); } } } }
代码说明
users/$(request.auth.uid)).data.managedBusinesses[0].id:用户文档包含managedBusinesses数组字段,其首个元素[0]为Firestore引用类型,尝试访问该引用类型的id属性。businesses/$(businessDocId)).data.team[0].id:商家文档包含team数组字段,其首个元素[0]为Firestore引用类型,尝试访问该引用类型的id属性。
测试数据(Rules Playground返回)
"managedBusinesses": [ "/databases/%28default%29/documents/businesses/TMCVfCRemRlaUdQjumrn" ]
原因分析与解决方案
核心原因
Firebase安全规则中,文档引用类型会被自动序列化为完整的文档路径字符串,而非具备.id属性的对象。Rules Playground返回的字符串格式就是规则中引用类型的实际存储形态,所以直接访问.id会得到undefined。
解决方案
要从路径字符串中提取文档ID,使用规则内置的split()方法拆分路径,取最后一段即可。优化后的isBusinessOwner()函数如下:
function isBusinessOwner() { // 获取用户文档并提取商家引用路径 let userDoc = get(/databases/$(database)/documents/users/$(request.auth.uid)); let businessRefPath = userDoc.data.managedBusinesses[0]; // 拆分路径获取商家ID let pathSegments = split(businessRefPath, "/"); let businessDocId = pathSegments[pathSegments.size() - 1]; // 获取商家文档并提取团队用户引用路径 let businessDoc = get(/databases/$(database)/documents/businesses/$(businessDocId)); let userRefPath = businessDoc.data.team[0]; // 拆分路径获取团队用户ID let userPathSegments = split(userRefPath, "/"); let businessTeamUserId = userPathSegments[userPathSegments.size() - 1]; return request.auth.uid == businessTeamUserId; }
内容的提问来源于stack exchange,提问作者Moody
相关产品推荐
相关产品推荐

