使用Firebase Firestore,我将聊天室详细信息存储在包含某些数据的文档中,例如:
roomName
roomAvatar
createDate
isDeleted
我的应用程序和规则要求在文档的“创建”上设置这些字段。但是,我也希望授权用户也可以“更新”该文档。
我已经进行过检查,仅允许某些用户更新文档并确认不允许他们修改“ createDate”之类的字段。但是,我似乎无法通过强制FiledValue.delete()或使用ref.set(objectMissingCreateDate)来创建强制授权用户不会删除“ createDate”字段的规则。
最后,如果他们只想更新一个或两个字段,我认为不需要客户端在更新中传递所有数据字段。
我有一个“更新”规则,如下所示:
allow update: if isAuthenticated() && isMemberOfRoom() &&
(
(!("roomName" in request.resource.data) ||
request.resource.data.roomName == resource.data.roomName ||
hasRoomPermission("UpdateRoom")) &&
(!("roomAvatar" in request.resource.data) ||
request.resource.data.roomAvatar == resource.data.roomAvatar ||
hasRoomPermission("UpdateRoom")) &&
(!("createDate" in request.resource.data) ||
request.resource.data.createDate == resource.data.createDate) &&
(!("isDeleted" in request.resource.data) ||
request.resource.data.isDeleted == resource.data.isDeleted ||
hasRoomPermission("DeleteRoom"))
);
主要问题是保护数据免受传入FieldValue.delete()或使用[Android] docRef.set()的授权用户的影响,而缺少必需的值。
我什至会接受为非管理员客户端关闭FieldValue.delete()和破坏性的“设置”操作的功能。
答案 0 :(得分:0)
借助Doug和Puff的评论,我意识到自己做错了。
首先,我不知道仅传递几个字段的更新(或带有合并选项的集合)将导致其余字段从数据库的request.resource
复制到resource
上
第二,集合(无合并)或传递FieldValue.delete()
是request.resource
缺少现有文档字段的唯一方法。
有了这些新知识,我将以前的规则更新为以下内容:
allow update: if isAuthenticated() && isMemberOfRoom() &&
(
("roomName" in request.resource.data &&
(request.resource.data.roomName == resource.data.roomName ||
hasRoomPermission("UpdateRoom"))) &&
("roomAvatar" in request.resource.data &&
(request.resource.data.roomAvatar == resource.data.roomAvatar ||
hasRoomPermission("UpdateRoom"))) &&
("createDate" in request.resource.data &&
request.resource.data.createDate == resource.data.createDate) &&
("isDeleted" in request.resource.data &&
(request.resource.data.isDeleted == resource.data.isDeleted ||
hasRoomPermission("DeleteRoom")))
);
这些新规则现在将createDate
锁定为客户端,同时允许通过权限测试的客户端编辑roomName
,roomAvatar
和isDeleted
。如果对象缺少这些字段之一,它也将不允许使用FieldValue.delete()
更新这些字段或调用docRef.set(object)
。