我不知道它是如何可能的,但即使安全规则拒绝新数据,它也会在我的视图中添加新对象。我听db如下:
dbRef = db.ref('/PostsCompany/' + companyKey + '/Posts').orderByChild('Date');
dbRef.on('child_added', function (snap) {
console.log(snap.val());
})
db结构:
{
"PostsCompany" : {
"-L3Y7zOHpKu0tbr-cyXQ" : {
"LastPost" : {
"CommentsEnabled" : true,
"CompanyKey" : "-L3Y7zOHpKu0tbr-cyXQ",
"Date" : 1517316150394,
"Message" : "test msg",
"PostKey" : "-L464lDsQc8wmpuynK_n",
"Type" : "Post"
},
"Posts" : {
"-L464lDsQc8wmpuynK_n" : {
"CommentsEnabled" : true,
"CompanyKey" : "-L3Y7zOHpKu0tbr-cyXQ",
"Date" : 1517316150394,
"Message" : "test msg",
"Type" : "Post"
}
}
}
}
}
相关规则:
"PostsCompany": {
"$companyKey": {
".read": "auth !== null",
"Posts": {
".indexOn": ["Date"],
"$postKey": {
".write": "auth.uid == root.child('CompanyPages')
.child($companyKey)
.child('OwnerUID')
.val()",
".validate": "root.child('CompanyPages')
.child($companyKey)
.exists() &&
newData.hasChildren(['CompanyKey','Message','Date','Type','CommentsEnabled'])",
"CompanyKey": {
".validate": "!data.exists() &&
newData.val() == $companyKey"
},
"Date": {
".validate": "!data.exists() &&
newData.val() <= now"
},
"Message": {
".validate": "!data.exists() &&
newData.isString() &&
newData.val().length<=1000"
},
"Type": {
".validate": "!data.exists() &&
newData.val() == 'Post'"
},
"Media": {
".validate": "!data.exists() &&
newData.hasChildren(['Type','Preview'])",
"Type" : {
".validate": "newData.val() == 'Image'"
},
"Preview" : {
".validate": "newData.isString()"
},
"$other": {
".validate": false
}
},
"CommentsEnabled": {
".validate": "newData.isBoolean()"
},
"Comments": {
".read": " auth !== null",
"$commentKey": {
".write": " auth !== null &&
root.child('PostsCompany')
.child($companyKey)
.child('Posts')
.child($postKey)
.child('CommentsEnabled')
.val() == true",
".validate": "newData.hasChildren(['UID','Message','Date'])",
"UID": {
".validate": "!data.exists() &&
auth.uid == newData.val()"
},
"Date": {
".validate": "!data.exists() &&
newData.val() <= now"
},
"Message": {
".validate": "!data.exists() &&
newData.isString() &&
newData.val().length<=1000"
},
"Likes": {
"$uidCommentLike": {
".write": "auth.uid == $uidCommentLike",
".validate": "newData.isBoolean()"
}
},
"Replies": {
"$replyKey": {
".validate": "newData.hasChildren(['UID','Message','Date'])",
"UID": {
".validate": "!data.exists() &&
auth.uid == newData.val()"
},
"Date": {
".validate": "!data.exists() &&
newData.val() <= now"
},
"Message": {
".validate": "!data.exists() &&
newData.isString() &&
newData.val().length<=1000"
},
"Likes": {
"$uidReplyLike": {
".write": "auth.uid == $uidReplyLike",
".validate": "newData.isBoolean()"
}
},
"$other": {
".validate": false
}
}
},
"$other": {
".validate": false
}
}
},
"Likes": {
"$uid": {
".write": "auth.uid == $uid",
".validate": "newData.isBoolean()"
}
},
"$other": {
".validate": false
}
}
}
}
},
当我尝试添加新帖子时,它会显示我预期的错误 (错误:PERMISSION_DENIED:权限被拒绝)。
但不知何故dbRef仍然有效并获取新数据。我在Firebase控制台上仔细检查它,它从不在db上添加新数据,或者至少在视觉上没有任何变化。
我想验证控件会在我的案例中使用newData.hasChildren()。如果没有发送其中一个对象(例如我尝试过没有Type),则会再次发生。
newData.hasChildren(['CompanyKey','Message','Date','Type','CommentsEnabled'])
答案 0 :(得分:0)
这样做的原因是Firebase进行了乐观更新。它会在与Google的数据库服务器版本同步之前,在数据库的本地版本中添加新帖子。
连接到Firebase数据库的每个客户端都维护自己的内部版本的任何活动数据。写入数据后,首先将其写入此本地版本。然后,Firebase客户端会在“尽力而为”的基础上与远程数据库服务器和其他客户端同步该数据。
请参阅: https://firebase.google.com/docs/database/web/read-and-write#write_data_offline
和
child_added
发生在执行规则之前,这就是在您的情况下运行规则的原因,并且您无法同时在Firebase Console中看到结果。
如果您定义child_removed
,则会在创建新帖子后直接将其称为。</ p>