根据以下规则,我得到了一个缺失或不充分的权限错误,但仅用于更新。我可以创建新文档,但任何更新写入都被拒绝。我错过了什么?
match /msgs/{msgs} {
allow create: if request.resource.data.keys().hasAll(["name", "msg", "status", "time"]) &&
request.resource.data.size() == 4 &&
request.resource.data.name is string &&
request.resource.data.msg is string &&
request.resource.data.status is string &&
request.resource.data.status == "new" || "viewed" &&
request.resource.data.time is timestamp;
allow update: if request.resource.data.size() == 1 &&
request.resource.data.keys().hasAll(["status"]) &&
request.resource.data.status is string &&
request.resource.data.status == "new" || "viewed";
}
我的更新代码非常简单:
docRef.update({
status: "viewed"
})
答案 0 :(得分:1)
我认为这里的问题是在update
上,尺寸不是' t"正在更新的字段数"而是更新后的对象大小应用于请求,但在提交更新之前#34;。这意味着request.resource.data
是"水合"除了正在编写的内容之外,还有现有的字段/值。然后,您将检查以确保只有一个字段在变化。
这意味着您的规则可能如下:
allow update: if request.resource.data.size() == resource.data.size() &&
request.resource.data.name == resource.data.name &&
request.resource.data.msg == resource.data.msg &&
request.resource.data.time == resource.data.time &&
request.resource.data.status == "new" || "viewed";
答案 1 :(得分:0)
收到Firebase支持团队的解决方案。事实证明,您需要使每个.data.key值声明分开且不同。所以正确的观察员才能完成这条规则:
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath){
if editingStyle == UITableViewCellEditingStyle.delete {
let delete: NSFetchRequest<Messages> = Messages.fetchRequest()
do {
var deleteMessage = try
PersistenceServce.context.fetch(delete)
PersistenceServce.context.delete(messages.remove(at: indexPath.row))
PersistenceServce.saveContext()
self.messages = deleteMessage
SavedMessages.reloadData()
} catch {}
}
}
是这样的:
var map = null;
var markers = [];
var infowindow = new google.maps.InfoWindow()
function clickOpenInfowindow (id) {
// find the marker by id
var marker = markers.find ( m => m.id === id)
if (marker) {
var content = '<h3>' + marker.name + '</h3>';
content += marker.address + '<br>';
content += maker.phone;
var clickaction = "click";
//check if mobile
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera
Mini/i.test(navigator.userAgent) ) {
clickaction = "click";
} else {
clickaction = "mouseover";
}
infowindow.setContent(content);
infowindow.open(map, marker);
}
}
function addMarker(info, icon) {
var location = {lat: info.lat, lng: info.lng};
var marker = new google.maps.Marker({
position: location,
icon: 'map/images/pin-icon-' + icon + '.png',
map: map
});
// save info content to marker
marker.id = info.id
marker.name = info.name
marker.addree = info.address
marker.phone = info.phone
var content = '<h3>' + info.name + '</h3>';
content += info.address + '<br>';
content += info.phone;
clickaction = "click";
//check if mobile
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera
Mini/i.test(navigator.userAgent) ) {
clickaction = "click";
} else {
clickaction = "mouseover";
}
google.maps.event.addListener(marker, clickaction, function() {
infowindow.setContent(content);
infowindow.open(map,marker);
});
markers.push(marker);
}
function addMarkerPerCategory(category) {
deleteMarkers();
if (category == 'ALL') {
for (var i = 0; i < mapPinInfo.restaurants.length; i++) {
addMarker(mapPinInfo.restaurants[i], 1);
}
for (var i = 0; i < mapPinInfo.transportation.length; i++) {
addMarker(mapPinInfo.transportation[i], 1);
}
for (var i = 0; i < mapPinInfo.shopping.length; i++) {
addMarker(mapPinInfo.shopping[i], 1);
}
} else if (category == 'RESTAURANTS') {
for (var i = 0; i < mapPinInfo.restaurants.length; i++) {
addMarker(mapPinInfo.restaurants[i], 1);
}
} else if (category == 'TRANSPORTATION') {
for (var i = 0; i < mapPinInfo.transportation.length; i++) {
addMarker(mapPinInfo.transportation[i], 1);
}
} else if (category == 'SHOPPING') {
for (var i = 0; i < mapPinInfo.shopping.length; i++) {
addMarker(mapPinInfo.shopping[i], 1);
}
}
}
function initMap() {
addMarkerPerCategory('ALL');
}
感谢大家的帮助。