自从程序启动以来,我尝试在时间戳内允许数据插入大约10秒,我有以下数据结构
启动程序时,我将当前时间戳保存在time
中,如下所示
firebaseRef.child("time").setValue(ServerValue.TIMESTAMP, listener);
firebaseRef.child("time").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
Long timestamp = (Long) dataSnapshot.getValue();
System.out.println(timestamp);
HashMap<String, Object> map = new HashMap<>();
map.put("time", timestamp);
firebaseRef.child("time").setValue(map, listener);
}
@Override
public void onCancelled(FirebaseError error) {
}
});
我做了以下安全规则
"items": {
".read": true,
".write": true,
".validate": "newData.parent().child('time').child('time').val() + 10000 >= now"
}
但它没有工作,我得到了许可被拒绝。我的规则有什么问题?
答案 0 :(得分:2)
其中一个问题当然是你正在初始化:
firebaseRef.child("time").setValue(ServerValue.TIMESTAMP, listener);
这会将time
的值设置为long。
{
"time": 1460776272703
}
但是:
HashMap<String, Object> map = new HashMap<>();
map.put("time", timestamp);
ref.child("time").setValue(map, listener);
您在setValue()
上拨打time
,然后使用time
密钥传递地图,最后写下time/time
。
{
"time": {
"time": 1460776272703
}
}
即使这是故意的,改变数据结构似乎也是一个坏主意。例如,在模拟器中,我很快遇到了这样的错误消息:
类型错误:+仅对数字和字符串进行操作。
因为它试图将JSON对象(上面第二个代码段中的/time
)作为数值进行评估。
我的工作代码段更简单:
Firebase ref = new Firebase("https://stackoverflow.firebaseio.com/36658910");
ref.child("time").setValue(ServerValue.TIMESTAMP, listener);
/*ref.child("time").addListenerForSingleValueEvent(new ValueEventListener() {
public void onDataChange(DataSnapshot dataSnapshot) {
System.out.println(dataSnapshot.getValue());
Long timestamp = (Long) dataSnapshot.getValue();
System.out.println(timestamp);
dataSnapshot.getRef().setValue(timestamp);
}
public void onCancelled(FirebaseError error) { }
});*/
我像这样运行,所以测试播种位置然后我再做一次运行,我禁用初始setValue()
并启用监听器,以测试更新。
相应的安全规则:
"time": {
".write": true,
".validate": "(!data.exists() && newData.val() == now) || newData.child('time').val() + 100000 >= now"
}
你会注意到我有一些单独的案例用于写入初始值(必须用ServerValue.TIMESTAMP
来匹配now
)和更新(必须在前一次写入后的100秒内) )。