firebase - 在 Firebase 实时数据库规则中,您如何为具有特定子值的用户授予写入权限?
问题描述
,"people" : {
".read": "auth != null",
"$uid": {
},
"e2" : {
".read": "auth.uid != null",
".write": "$uid == auth.uid"
},
"l1" : {
".read": "auth.uid != null",
".write": "auth.uid != null"
}
所以 e2 是电子邮件的@。例如@gmail 或@aol 或@yahoo。对于 l1 孩子,我想制定写规则:写 if auth.uid != null && e2 与你正在写 l1 的人的 e2 具有相同的值。我能得到的最远的是这样的:
"data.parent().child(people).hasChildren(['auth.uid', 'l1'])"
JSON
"people": {
"02PdiNpmW3MMyJt3qPuRyTpHLaw2": {
"e2": "aol.com",
"l1": 4,
"X": {
"e2": "aol.com",
"l1": 0,
"P": {
"e2": "gmail.com",
"l1": 0,
基本上 l1 = like,所以一个用户以将计数加 1 的形式写入另一个用户的 l1。
应该成功的操作:
用户 X 想要喜欢 uid 为 02PdiNpmW3MMyJt3qPuRyTpHLaw2 的用户。用户 X 有一个 @aol.com 的 e2 子级。这与他想要喜欢的用户的e2孩子相同。用户 x 也是授权用户,因此他满足 2 个要求来写他想要喜欢的用户的 l1。
不应该成功的操作:
用户 P 想要喜欢 uid 为 02PdiNpmW3MMyJt3qPuRyTpHLaw2 的用户。用户 P 有一个 @gmail.com 的 e2 子级。这和他想要喜欢的用户的e2孩子不一样。因此,用户 P 不满足写给他想要喜欢的用户的 l1 的要求
解决方案
这是一个非常复杂的场景,所以我将逐步介绍它。您很有可能需要进行更改以使这些规则适用于您的完整用例,因此我希望每个步骤都可以让您自己调整它们。
第一步是去混淆你的数据结构。我将改为使用此结构开始:
{
"people" : {
"user1" : {
"domain" : "aol.com",
"likeCount" : 2,
"likers" : {
"user2" : {
"comain" : "aol.com"
},
"user3" : {
"domain" : "aol.com"
}
}
}
}
}
所以user1
有两个喜欢,来自user2
同user3
一个域。
我强烈建议在您的数据库中使用像这样有意义的名称,但绝对是在您发布的有关它的问题中。如果人们不能轻易理解您的数据模型,那么他们提供帮助的机会就会迅速下降。
在上述数据模型中,我们可以确保只有来自同一域的用户可以通过以下方式点赞该用户:
"people": {
"$uid": {
"likers": {
"$likerid": {
".write": "data.parent().parent().child('domain').val() == newData.child('domain').val()"
}
}
}
}
有了这些规则,我尝试了两次对people/user1/likers/user4
. 第一个操作成功:
{
"domain": "aol.com"
}
第二个操作失败:
{
"domain": "gmail.com"
}
我们可能还应该确保用户只能写自己喜欢的内容,而不能写给其他用户。我们可以这样做:
"people": {
"$uid": {
"likers": {
"$likerid": {
".write": "$likerid == auth.uid &&
data.parent().parent().child('domain').val() == newData.child('domain').val()"
}
}
}
}
接下来,我们将添加一个规则,允许用户喜欢某人,前提是他们以前没有喜欢过某人。我们将继续这样做,因为people/$uid
我们需要很快查看数据。likers
likesCount
第一步的规则是:
"people": {
"$uid": {
".write": "
!data.child('likers').child(auth.uid).exists() && newData.child('likers').child(auth.uid).exists()
",
"likers": {
"$likerid": {
".write": "$likerid == auth.uid &&
data.parent().parent().child('domain').val() == newData.child('domain').val()"
}
}
}
因此,如果我们要添加尚不存在的类似内容,这些规则允许我们向用户写信。您可能需要在此处进行额外检查以允许更新其他子节点,但在这里我们将保持尽可能简单(因为它已经非常复杂了)。
最后,您要确保写入还必须增加likeCount
,这应该是这样的:
"people": {
"$uid": {
".write": "
!data.child('likers').child(auth.uid).exists() && newData.child('likers').child(auth.uid).exists()
&& newData.child('likeCount').val() == data.child('likeCount').val() + 1
",
"likers": {
"$likerid": {
".write": "$likerid == auth.uid &&
data.parent().parent().child('domain').val() == newData.child('domain').val()"
}
}
}
所以新行现在检查新数据likeCount
是否比之前的值高一个。
我已经在自己的测试数据库中采取了上述每个步骤,并在操场上测试了正面和负面案例。因此,虽然可能存在一些问题,但每个步骤的基本方法都有效。
如前所述,这非常复杂,您很可能需要进行重大更改才能完全适用于您的所有用例。
推荐阅读
- angular - 如何在 Angular 中导航(重定向)到我想要的任何页面?
- html - 用于在移动设备中心定位徽标的 CSS 媒体查询
- python-3.x - flask_script 问题 python 3.4
- vue.js - Vue.js:Leaflet-Marker 不可见
- c - 使用动态数组按字典顺序对输入进行排序
- ios - 带有填充和圆角的图标 - Xamarin Forms 的 iOS 自定义渲染器
- c++ - 错误:为什么“void*”不是指向对象的指针类型,即使指针设置为对象?
- html - 在 Bootstrap 中的输入表单字段旁边添加一个红色 *
- python - Python,如何使用列表中输入的项目并使用它们来分配另一个值?可能吗
- java - 将一堆图像从 Android 手机发送到 PC