public 和私有字段的 Firestore 安全规则

Firestore security rules for public and private fields

关于 Firebase 实时数据库的安全规则,public 和私有数据可以存在于同一棵树中,例如使用以下规则。

然而,当使用 Firestore 时,它​​似乎并不能使我们做同样的事情,因为我们可以检索的数据块仅在集合或文档下。 当 public 和私有数据在同一个文档中定义并使用 collection/document 获取数据时,如果我们不是所有者,我们将得到私有数据权限不足的错误。

当使用RTDB时,我们可以得到'users/{userId}/publicInfo'的数据,因为我们不知道collection/document。

有什么方法可以使用 Firestore 对 RTDB 执行此操作?否则,我们应该public/private单独收集?

// rule of Firebase Realtime Database
"users": {
   "$user_id": {
       ".read": "auth.uid === $user_id",
       ".write": "auth.uid === $user_id",

       "private": {
          ".read": "auth.uid === $user_id"   // --- private data
       }

       "public": {
          ".read": "auth !== null";           // --- public data 
       }
   }
}

// Firestore
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId} {

      match /{private=**} {
        allow read, write: if request.auth == userId;
      }

      match /{public=**} {
        allow read, write: if request.auth != null;
      }
    }
  }
}

因此您不能为文档的不同部分设置单独的安全规则。您可以阅读整个文档,也可以不阅读。

就是说,如果您想为您的 userID 文档提供一个 "public" 和 "private" 子集合,其中包含 public 和私有的文档,那是您完全可以做到的,只是不是您当前设置安全规则的方式。

您所写的 match /{private=**} 位并不意味着 "Match any subcollection that's called 'private'"。这意味着,"Match any subcollection, no matter what, and then assign it to a variable called private"。文档的“Recursive matching with wildcards”部分更详细地介绍了这一点。

此外,您需要参考 request.auth.uid 以获取用户 ID。

所以,您可能想要更像这样的东西:

// Firestore
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId} {
      // You'll probably want to add security rules around the user document 
      // itself. For now, though, let's look at our subcollections:

      match /private/{anything=**} {
        // Only the user can read documents in their private collection
        allow read, write: if request.auth.uid == userId;
      }

      match /public/{anything=**} {
        // Anybody can read documents here, as long as they're signed in
        allow read, write: if request.auth != null;
      }
    }
  }
}

您可以将 visibility 属性 添加为每个文档的值:public/private,并确保您有 userid字符串或数组(用于多用户访问)

然后您可以编写安全规则来检查属性 visibilityuserid

查看 firestore 文档中的示例。

额外内容

  • 这也使得它可以使用 shared 或更多道具进行扩展。
  • 您不必复制索引
  • 更改可见性时不必移动文档