是否可以根据特定字段创建Firestore规则?

时间:2020-06-30 17:03:36

标签: firebase google-cloud-firestore firebase-security

我将在这里尝试概括一下,以使问题更简单。我有一个Firestore数据库,用于存储用户和论坛帖子。我正在尝试专门为论坛帖子编写规则。

match /databases/{database}/documents {
    function isSignedIn() {
        return request.auth != null
    }
    function isOwner(userID) {
        return request.auth.uid == userID
    }

// ...
    match /forum/{topicID} {
        allow read: if true
        allow create: if isSignedIn()
        allow update, delete: if isSignedIn()
    }
}

因此,在这里,我已经掌握了它,以便您可以登录后创建,更新和删除。我还需要使用isOwner()添加选中项“他们是否拥有此信息?”功能。

这很令人毛骨悚然,但是我的问题是-每个论坛帖子(AKA主题)中都有两个字段,任何登录的人都可以更新。这些字段是likeslikeCount

likes是一个字符串数组,每个字符串都是用户的ID。 likeCount是等于likes数组长度的数字。

我开始发现,如果likes是一个子集合,而likeCount可能只是likesSnapshot.docs.length,这会更容易。我只是担心可能涉及的重新编码量!

长话短说,我想按照以下方式做点事情:

match /forum/{topicID} {
    allow read: if true
    allow create: if isSignedIn()
    allow update, delete: if isSignedIn() && isOwner(resource.data.user.id)
    match /likes && /likeCount {
        allow create, update: if isSignedIn()
        allow delete: if isSignedIn() && isOwner([THE USER ID THAT IS BEING REMOVED FROM THE ARRAY])
    }
}

...但是我不确定最好的解决方法!

请先感谢您:)

2 个答案:

答案 0 :(得分:1)

像在安全规则中显示的那样,无法定位特定字段。您只能使用match语句匹配整个文档。

如果要确保某些用户只能修改某些字段,可以使用MapDiff api来检查文档数据中仅那些字段被更改。它会像这样:

if isSignedIn() &&
  request.resource.data.diff(resource.data).affectedKeys().hasOnly(["likes", "likeCount"])

如果仅修改了Likes和LikesCount且用户已登录,它将评估true

答案 1 :(得分:0)

是的,您可以这样做。实际上,我最近是在自己的论坛上做到的。

方法是允许isOwner更新,并限制非所有者能够更新的内容。您可以这样做:

allow update: if request.auth.uid != null
   && request.resource.data.{some field} == resource.data.{some field}
   && request.resource.data.title.{some other field} == resource.data.{some other field}

将您不希望非所有者能够更新的所有数据字段放入{some field}占位符中。规则是检查某些字段是否未更改,从而限制了允许用户更改文档中的内容。

然后允许所有者完全更新特权:

allow update: if isOwner()