Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/firebase/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用firebase规则检查用户组数组和记录组数组是否相交_Firebase_Firebase Security - Fatal编程技术网

如何使用firebase规则检查用户组数组和记录组数组是否相交

如何使用firebase规则检查用户组数组和记录组数组是否相交,firebase,firebase-security,Firebase,Firebase Security,我在firebase中有一个记录列表,其中包含一个组属性,其中包含零个或多个组。我还有firebase auth对象,它上也有零个或多个组。我想为我的记录设置一个.read firebase规则,该规则将检查两个列表中是否至少存在一个组 换句话说,我有一个用户,该用户拥有一组已分配给它的组。我有一些记录,其中也有一些组列表,指定用户必须访问哪些组。如果登录用户尝试访问该记录,我希望确保该用户至少有一个记录所需的组 在客户机上,我会执行类似于.intersect(用户组、记录组).length>0

我在firebase中有一个记录列表,其中包含一个组属性,其中包含零个或多个组。我还有firebase auth对象,它上也有零个或多个组。我想为我的记录设置一个.read firebase规则,该规则将检查两个列表中是否至少存在一个组

换句话说,我有一个用户,该用户拥有一组已分配给它的组。我有一些记录,其中也有一些组列表,指定用户必须访问哪些组。如果登录用户尝试访问该记录,我希望确保该用户至少有一个记录所需的组

在客户机上,我会执行类似于
.intersect(用户组、记录组).length>0

我不确定如何在firebase规则表达式中执行此操作。如果它能像这样工作,那就太酷了

记录:

{
  someData: "test"
  groups: ['foo', 'bar']
}
Firebase身份验证对象:

{
  userName: "Bob",
  groups: ['foo', 'bar']
}
规则数据:

{
  "rules": {
    "records": {
      "$recordId": {
        ".read": "data.child('groups').intersectsWith(auth.groups)"
      }
    }
  }
}
谢谢

更新: 我认为如果haschilds()使用| |而不是&&的话,我可以将组名放在它们的键位置,并通过这种方式检查它们是否存在。类似于
“data.child('groups')。haschilds(auth.groups,'or')”

其中记录:

{
  someData: "test"
  groups: {
    'foo': '',
    'bar': ''
  }
}
更新2: 根据加藤的评论和链接,我意识到即使有孩子也能做到,或者它仍然不能很好地工作。对单个记录的请求可以工作,但如果当前用户没有访问每个记录的权限,则对所有记录的请求都会出错


目前还不清楚如何构建数据以实现这一目标。如果一个记录可以属于多个组,那么该如何工作?这是一个非常常见的场景(基本上是linux组权限的工作方式),所以我不是唯一一个尝试这样做的人。有人有任何想法/例子来说明如何在firebase中实现这一点吗?

目前,我认为这是不可能的。允许的变量、方法和运算符数量有限,如下所示:

由于规则中不允许使用函数定义,因此您不能像调用array.some(callback)这样对数组执行任何操作,以便自己进行匹配

我知道你有三个选择:

1) 复制数据,这样就不需要进行检查。这就是我在我的项目中所做的:我希望在网络列表中共享网络的用户可以使用一些用户数据(名称)。最初我想检查两个成员的网络列表,看看是否至少有一个匹配。最终我意识到,将每个用户的名字保存为网络数据的一部分会更容易,这样就不必进行需要这种奇怪权限的用户查找。我对您的数据了解不够,无法建议您需要复制什么

2) 使用字符串而不是数组。您可以将一个字符串转换为正则表达式(或仅以正则表达式格式保存),然后使用它搜索另一个字符串以查找匹配项


3) 如果您有足够多像这样奇怪的情况,请实际运行一个服务器,以自定义方式验证请求。在数据库中,只允许对服务器拥有权限。现在,还有另一种可能性:使用Firestore交付内容,可能与实时数据库同步

在Firestore中,您可以创建如下规则:

function hasAccessTo(permissionList) {
  return get(/databases/$(database)/documents/permissions/$(request.auth.uid))
      .data.userPermissions.keys().hasAny(permissionList)
}

match /content/{itemId} {
  allow read: if hasAccessTo(resource.data.permissions.keys());
}
以下数据将允许$UID读取$CONTENTID,因为用户权限集与访问内容所需的可能权限相交(使用
access123
)。我的设想是,一段内容可以通过多次应用内购买解锁

{
  permissions: { 
    $UID: { userPermissions: { access123:true, access456:true } },
    ...
  },
  content: { 
    $CONTENTID: { ..., permissions: { access123, access789 } },
    ...
  }
}
对于渐进式迁移,您可以使用如下单向云函数保持实时数据库和Firestore之间的数据同步,例如:

exports.fsyncContent = functions.database
  .ref("/content/{itemId}")
  .onWrite((snapshot, context) => {
    const item = snapshot.after.val();
    return admin
      .firestore()
      .collection("content")
      .doc(context.params.itemId)
      .set(item);
  });

Firebase安全规则。如果要检索记录,您可能需要按组存储记录。但不确定该如何操作。用户属于多个组,记录属于多个组。只要他们都有一个共同访问的组,就应该提供。对此有任何更新吗?我有一个类似的问题,我正试图解决完全相同的问题@yodaisgreen您找到解决方案/解决方法了吗?这已经是一年前的事了,。。你还在为这个问题寻找答案吗@但是,似乎不能将数据库中存储的字符串用作regexp,对吗?我认为regexp必须事先在rulesYeah中编写。不能对数据库中存储的正则表达式模式字符串使用
matches()
规则。它会说,
matches()需要一个正则表达式文本参数。