在Firestore规则中声明函数 [英] Declaring a function in Firestore rules

查看:40
本文介绍了在Firestore规则中声明函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我现在所面临的Firestore安全规则问题.

Here is a problem I am facing now with the Firestore security rules.

首先,这里是我的Firestore数据库中的数据结构示例:

First of all here is an example of data structure I have in my firestore database:

userProfiles/userId/userData

companies/companyId/companyData

看起来很简单.每个userData都包含一个名为companies的数组,其中包含该用户有权访问的所有companyId.

Looks pretty simple. Each userData includes and array named companies which includes all companyIds which this user has access to.

现在,我需要编写规则以仅在companyId特别是用户信息公司列表中才允许读取companyData.

Now I need to write rules to allow read companyData only if companyId is in particular user info companies list.

以下是对我来说起作用的规则:

Here are the rules which work for me:

service cloud.firestore {
  match /databases/{database}/documents {
    match /companies/{companyId} {
      allow read: if companyId in get(/databases/$(database)/documents/userProfiles/$(request.auth.uid)).data.companies
    }
  }
}

基于我将要拥有更多规则的事实,我想使它们更具可读性和重用性.根据此官方指南,我可以创建自定义函数并根据对此文章来说,它们可以是通用的,并且可以在主体之外声明规则博克.

Taking the fact that I am going to have much more rules, I would like to make them more readable and comfortable to reuse. According to this official guide I can create custom functions and according to this article they can be common and declared outside of the main rules bock.

我重构了规则,使其看起来像这样,并且对我也有效:

I refactored my rules to look like this and it also worked for me:

service cloud.firestore {
  match /databases/{database}/documents {
    match /companies/{companyId} {
      allow read: if companyId in getUserCompanies()
    }
    function getUserCompanies() {
        return get(/databases/$(database)/documents/userProfiles/$(request.auth.uid)).data.companies
    } 
  }
}

但是现在我想将功能移到规则块之外以使其更加清晰:

But now I would like to move function outside of the rules block to amke it even more clear:

service cloud.firestore {
  match /databases/{database}/documents {
    match /companies/{companyId} {
      allow read: if companyId in getUserCompanies()
    } 
  }
}

function getUserCompanies() {
    return get(/databases/$(database)/documents/userProfiles/$(request.auth.uid)).data.companies
}

那是行不通的.没有任何错误,我只是从模拟器收到常规的Read denied消息.

And that doesn't work. There is no any errors, I just receive the regular Read denied message from the simulator.

因此问题是:是否可以像我在示例中所做的那样将函数移到外部?我在这里犯了任何明显的错误吗?有没有更好的方法可以使我的规则更加明确?

So the questions are: is it possible to move function outside as I did it in my example? Are there any obvious mistakes I've done here? is there better way to make my rules set even more clear?

P.S. 我还尝试将一些参数传递给该函数,包括用户名和公司ID-不用运气.

P.S. I also tried to pass some parameters to that function, including user and company ids - no luck.

推荐答案

可以在规则文件中的任何级别上定义函数.但是它们只能访问在定义它们的作用域中定义的变量.您还必须将其他任何内容作为变量传递.

Functions can be defined on any level in your rules file. But they only have access to variables that are defined in the scope where you define them. Anything else you have to pass in as a variable.

因此,此(无用的)函数在全局定义时有效:

So this (useless) function works when defined globally:

function isTrue() {
  return true;
}

但是这个不会,因为它没有访问request的权限:

But this one won't, because it doesn't have access to request:

function isAdmin() {
  return (request.auth.token.email_verified && 
    request.auth.token.email.matches(".*@google.com"));
}

我有时要做的是在函数定义中添加一个参数:

What I sometimes do is add a parameter to the function definition:

function isAdmin(request) {
  return (request.auth.token.email_verified && 
    request.auth.token.email.matches(".*@google.com"));
}

,然后将变量传递给调用:

and then pass the variable in to the call:

  allow update: if isAdmin(request) || 
    (request.auth.uid == uid && isUnmodified(request, resource, 'name'));

这篇关于在Firestore规则中声明函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆