在Firebase实时数据库规则中,如何为具有特定子值的用户授予写访问权限? [英] In Firebase Realtime Database Rules, how do you give write access to the users with a certain child value?

查看:26
本文介绍了在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子级,我要制定写入规则:如果auth.uid!= null&&e2与您要写给l1的人的e2具有相同的值.我能得到的最远的东西是这样的:

So e2 is the @ of an email. For example @gmail or @aol or @yahoo. For the l1 child, I want to make the write rule: Write if auth.uid != null && e2 has the same value as the e2 of the person you are writing l1 to. The furthest I could get, is something like this:

"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.

Basically l1 = like, so a user writes to another users's l1 in the form of adding 1 more to the count.

应该成功的操作:

用户X希望喜欢使用uid 02PdiNpmW3MMyJt3qPuRyTpHLaw2的用户.用户X的e2子级为@ aol.com.这与他想要喜欢的用户的e2子代相同.用户x也是授权用户,因此满足写给他想要的用户l1的2个要求.

A user X wants to like the user with uid 02PdiNpmW3MMyJt3qPuRyTpHLaw2. User X has a e2 child of @aol.com. This is the same as the e2 child of the user he wants to like. User x is also an authorized user, therefore he meets the 2 requirements to write to the l1 of the user he wants to like.

不成功的操作:

用户P希望使用uid 02PdiNpmW3MMyJt3qPuRyTpHLaw2的用户.用户P的e2子级为@ gmail.com.这与他要喜欢的用户的e2子代不同.因此,用户P不满足写给他想要的用户的l1的要求

User P wants to like the user with uid 02PdiNpmW3MMyJt3qPuRyTpHLaw2. User P has a e2 child of @gmail.com. This is not the same as the e2 child of the user he wants to like. User P therefore does not meet the requirement to write to the l1 of the user he wants to like

推荐答案

这是一个真正涉及的场景,因此我将逐步介绍它.您很有可能需要进行更改,以使这些规则适用于您的完整用例,因此,我希望每个步骤都能使您自己进行调整.

This is a really involved scenario, so I'm going to walk through it step-by-step. There is a good chance you'll need to make changes to make these rules work for your complete use-case, so I'm hoping that having each step will make it possible for you to tune them yourself.

第一步是对数据结构进行模糊处理.相反,我将使用此结构来开始:

The first step is to deobfuscate your data structure. I'll instead use this structure to get started:

{
  "people" : {
    "user1" : {
      "domain" : "aol.com",
      "likeCount" : 2,
      "likers" : {
        "user2" : {
          "comain" : "aol.com"
        },
        "user3" : {
          "domain" : "aol.com"
        }
      }
    }
  }
}

user1 有两个喜欢,分别来自同一域的 user2 user3 .

So user1 has two likes, by user2 and user3 both from the same domain.

高度建议您在数据库中总体上使用这样有意义的名称,但绝对会在您发布有关该问题的问题时使用.如果人们不容易理解您的数据模型,那么他们提供帮助的机会就会迅速下降.

I highly recommend using meaningful names like this in your database in general, but definitely in questions that you post about it. If people can't easily understand your data model, chances of them helping go down rapidly.

在上述数据模型中,我们可以确保只有来自同一域的用户才能通过以下方式喜欢该用户:

In the above data model, we can ensure that only users from the same domain can like this user with:

  "people": {
    "$uid": {
      "likers": {
        "$likerid": {
          ".write": "data.parent().parent().child('domain').val() == newData.child('domain').val()"
        }
      }
    }
  }

使用这些规则,我尝试了对 people/user1/likers/user4 的两次写操作.第一个操作成功:

With these rules, I've tried two write operations to people/user1/likers/user4. The first operation succeeds:

{
  "domain": "aol.com"
}

第二项操作失败:

{
  "domain": "gmail.com"
}


我们可能还应该确保用户只能写自己的喜欢,而不能写其他用户.我们可以这样:


We should probably also ensure that a user can only write their own likes, and not for other users. We can do that with:

  "people": {
    "$uid": {
      "likers": {
        "$likerid": {
          ".write": "$likerid == auth.uid && 
            data.parent().parent().child('domain').val() == newData.child('domain').val()"
        }
      }
    }
  }


接下来,我们将添加一条规则,该规则允许用户只有在以前不喜欢某人的情况下才喜欢某人.我们将在 people/$ uid 上执行此操作,因为我们需要尽快查看 likers 下和 likesCount 下的数据.


Next up, we'll add a rule that allows a user to like someone, only if they haven't liked them before. We'll do that on people/$uid as we'll need to look at data under likers and under likesCount soon.

第一步的规则是:

  "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()"
        }
      }
    }

因此,如果要添加尚不存在的赞,这些规则将使我们能够写给用户.您可能需要在此处进行其他检查,以允许其他子节点的更新,但是在这里,我们将使事情尽可能简单(因为它已经相当复杂了).

So these rules allow us to write to a user, if we are adding a like that doesn't exist yet. You may need to do additional checks here to allow updates of other child nodes, but for here we'll keep things as simple as possible (as it's already pretty involved).

最后,您要确保写入操作还必须增加 likeCount ,它应该是这样的:

Finally you want to ensure that the write must also increment the likeCount, which should be something like this:

  "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 处的新数据是否比以前的值高一个.

So the new line now checks if thew new data at likeCount is one higher than its previous value.

我已经在自己的测试数据库中完成了上述每个步骤,并在操场上对阳性和阴性病例进行了测试.因此,尽管可能存在一些问题,但每个步骤的基本方法都行得通.

I've taken each of the steps above in a test database of my own, and tested in the playground with both positive and negative cases. So while there may be some issues, the basic approach of each step works.

正如所说的,这很复杂,很可能需要做出重大更改,才能对所有用例完全起作用.

As said this is pretty involved, and it's quite likely that you'll need to make significant changes before it fully works for all your use-cases.

这篇关于在Firebase实时数据库规则中,如何为具有特定子值的用户授予写访问权限?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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