Firebase原子写

时间:2016-12-09 15:19:11

标签: firebase firebase-realtime-database

我想确保总是将2个值一起写入实时数据库。

我有以下布局:

- > register_username

- - > uid_lookup

- - - > “some_username”:“some_uid”

- - > username_lookup

- - - > “some_uid”: “some_username”

这些是规则(对不起格式化):

// uid -> username && username -> uid
"register_username": {

  ".write":                 "auth !== null",
  ".validate":          "newData.hasChildren(['uid_lookup', 'username_lookup'])",

    // username -> uid
  "uid_lookup": {

    "$username": {
      ".validate":  "newData.val() === auth.uid && !data.exists()"
    }

  },

  // uid -> username
  "username_lookup": {

    ".write":       "!data.exists()",

    "$uid": {
      ".validate":  "auth.uid === $uid && newData.val().matches(/^[a-zA-Z0-9-_]{4,20}$/) && newData.parent().parent().child('uid_lookup/' + newData.val()).exists()"
    }

  },

  // don't allow any other children
  "$other":             {".validate": false}

}

写作时

{
  "uid_lookup": {
    "username": "123"
  },
  "username_lookup": {
    "123":"username"
  }
}

/register_username/它运行正常。

但为什么我只能写/register_username/uid_lookup/而不会收到错误?

2 个答案:

答案 0 :(得分:1)

Firebase数据库安全规则在写入操作之前和之后验证数据库的状态。他们没有验证delta。

因此,您不应该尝试捕获非法写入。相反,您应该编写规则以仅允许合法的数据结构。

对于"$username": { ".validate": "newData.val() === auth.uid && !data.exists() && newData.parent().parent().child('username_lookup').child(auth.uid).exists()" } 下的数据,您指定的是用户只能编写自己的uid。您可能希望添加一个子句,以确保它们只能编写一个也具有映射用户名的uid:

{{1}}

答案 1 :(得分:0)

Permission cascades down in Firebase:一旦您授予了树中特定级别的用户权限,您就无法在较低级别获取该权限。

您的规则首先将/register_username的写规则定义为:

".write": "auth !== null",

这意味着任何经过身份验证的用户都可以在/register_username下写入所有数据(包括该节点本身)。