我正在实施用户和事件系统。一个限制是用户一次只能托管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=>{
...
})
},
更新调用的问题是它总是失败。我试图同时插入hosts
和events
。但是events
write
规则要求userId在写入之前处于hosts
,所以我想这就是它失败的原因。
我必须进行2次单独更新吗? 1将userId插入hosts
,然后如果成功,另一个插入events
?
答案 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"
}
}