系统函数
安全规则内置了一系列系统级函数,这些函数提供强大的通用能力,使开发者能够在规则表达式中直接调用,实现更灵活的资源访问权限控制。
get
静态函数
语法: get(path)
返回: document 对象
功能: 根据指定路径获取文档内容。
参数
参数 | 类型 | 说明 |
---|---|---|
path | string | 非空,格式为 database.集合名称.文档ID 的字符串。可通过多种方式计算得到,例如使用字符串模板进行拼接:`database.${doc.collection}.${doc._id}` |
返回值
- 如果文档不存在,返回
undefined
或null
- 如果文档存在,返回包含文档数据的 document 对象
使用示例
示例1: 用户权限存储在独立文档中,使用数值表示权限范围
{
"read": "get('database.test.123')[auth.uid] in [1,2,3]",
"delete": "get('database.permissions.user_rights')[auth.uid] == 1 && doc.user in ['user1','user2']"
}
示例2: 跨集合权限验证 - 集合A包含shopId、orderId关联关系,集合B包含owner、shopId关联关系,限制用户只能查询有权限的商店订单
{
"read": "auth.openid in get(`database.B.${doc.shopId}`).owner"
}
使用限制
- 当
get
参数中包含doc
变量时,该变量需要在查询条件中以==
或in
方式出现。如使用in
方式,只允许in
单一值,即doc.shopId in array
且array.length == 1
- 单个表达式中最多可使用
3
个get
函数,最多可访问10
个不同的文档 get
函数的嵌套深度最多为2,即可以使用get(get(path))
形式,但不能更深层嵌套
性能说明
每次调用get
函数都会产生数据库读取操作:
- 不使用变量时:每个
get
产生一次读操作 - 使用变量时:每个
get
对应每个变量值会产生一次读操作
例如: 规则 get(`database.collection.${doc._id}`).test
,在查询 _.or([{_id:1},{_id:2},{_id:3},{_id:4},{_id:5}])
时会产生5次读取操作。
系统会对相同文档、相同字段的读取进行缓存优化。在可能的情况下,安全规则会合并部分相同文档不同字段的读取,在一次操作中获取多个字段,以减少数据库资源消耗。合并效率与规则的复杂度和写法相关。