firebase多路径更新和每条路径的规则

时间:2017-06-10 18:54:14

标签: javascript firebase firebase-realtime-database firebase-security

我正在实施用户和事件系统。一个限制是用户一次只能托管1个事件。

我最初尝试通过查找已经有userId等于events的事件来查询events .write规则中的auth.uid节点来实施限制。但是我无法弄清楚如何做到这一点,所以我决定创建一个新节点hosts作为查找表。它只存储当前正在托管事件的任何userId。如果用户尝试创建活动,并且他们的userId已存在于hosts中,则表示错误。

规则:

{
  "rules":{
        "users":{
            "$uid":{
                ".read": "auth.uid == $uid",
              ".write": "auth.uid == $uid",
              ".validate": "newData.exists()"
          }
      },
      "hosts":{
            "$uid":{
                ".read": "true",
                //to be a host, you must be a user
              ".write": "auth.uid == $uid &&    root.child('users').hasChild(auth.uid) &&   !root.child('hosts').hasChild(auth.uid)",
              ".validate": "newData.exists()"
          }
      },
      "events":{
          "$uid":{
                ".read": "true",
                //to create an event, you must be a host
              ".write": "root.child('hosts').hasChild(auth.uid)",
              ".validate": "true"
          }
      }
  }
}

Javascript:

createEvent(form){
    var user = firebase.auth().currentUser
    var db = firebase.database();
    var newEventRef = db.ref('events').push();
    var newEvent = {}
    newEvent[uid] = form*/

    var update = {
        ['hosts/'+user.uid]: true
        update['events/'+newEventRef.key] = form
    };
    db.ref().update(update)
        .then((...args)=>{
            ...
        })
        .catch(err=>{
            ...
        })
},

更新调用的问题是它总是失败。我试图同时插入hostsevents。但是events write规则要求userId在写入之前处于hosts,所以我想这就是它失败的原因。

我必须进行2次单独更新吗? 1将userId插入hosts,然后如果成功,另一个插入events

1 个答案:

答案 0 :(得分:1)

在安全规则中,有三个引用数据的变量:

  • data - 更新之前规则位置存在的数据
  • newData - 更新后规则所在位置的数据
  • root - 在更新
  • 之前存在于数据库根目录的数据

因此,当您在规则中引用root时,您会在更新之前获得数据。要获取更新的数据,您必须参考newData。由于遗憾的是没有newRoot,您必须多次拨打newData,从parent()导航到所需级别。

一旦例子:

  "events":{
      "$uid":{
            ".read": "true",
            //to create an event, you must be a host
          ".write": "newData.parent().parent().child('hosts').hasChild(auth.uid)",
          ".validate": "true"
      }
  }