首页 > 解决方案 > Firestore:如何设置基于阵列的安全规则?

问题描述

我正在开发一个应用程序,您可以在其中关注/取消关注其他应用程序用户。所以在firestore中我有一个用户集合,每个用户都包含一个名为followers的属性。Followers 是一组用户 ID。

像这样:

"users": {
    "user1": { 
        "name": "Jack", 
        "imageUrl": "http://lorempixel.nl",
        "followers": ["user1", "user2"]
    }
}

问题

如何在firestore中编写安全规则,以便只有当前用户可以读取/写入自己的对象,但其他人可以将其用户ID添加/删除到关注者数组中。

标签: firebasenosqlgoogle-cloud-firestorefirebase-security

解决方案


为了使人们能够关注/取消关注用户,这组安全规则应该适用于您的数据结构。基础意味着他们不能更改其他数据,并且有 3 条规则:

  1. 允许他们添加自己,这意味着用户可以将他们的uid添加到关注者列表中,但不能删除其他人
  2. 允许他们删除他们的 uid 但没有其他人
  3. 如果他们在关注后碰巧更新了文档,他们将无法修改它。

    service cloud.firestore {
    
        match /databases/{database}/documents {
    
            match /users/{userId} {
            allow update: if 
                resource.data.name == request.resource.data.name &&
                resource.data.imageUrl == request.resource.data.imageUrl &&
                request.resource.data.size() == resource.data.size() &&
                ( 
                    (
                        // If user adding their uid
                        request.resource.data.followers.hasAll(resource.data.followers) &&
                        request.resource.data.followers.hasAll([request.auth.uid]) &&
                        request.resource.data.followers.size() == resource.data.followers.size() + 1
                    ) || 
                    (
                        // If user removing their uid
                        resource.data.followers.hasAll(request.resource.data.followers) &&
                        resource.data.followers.hasAll([request.auth.uid]) &&
                        !request.resource.data.followers.hasAll([request.auth.uid]) &&
                        request.resource.data.followers.size() == resource.data.followers.size() - 1
                    ) || 
                    (
                        // If user tries updating whilst already a follower
                        request.resource.data.followers.hasAll(resource.data.followers) &&
                        request.resource.data.followers.size() == resource.data.followers.size()
                    )
                )
            }
        }
    }
    

我已经在 Firebase 控制台的规则模拟器中对其进行了测试,所以应该一切正常,但请进行广泛的测试。感觉非常 hacky,并且有特定的规则来支持数组删除肯定会很好,但我相信这应该同时做到。


推荐阅读