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
字符串或数组(用于多用户访问)
然后您可以编写安全规则来检查属性 visibility
和 userid
。
查看 firestore 文档中的示例。
额外内容
- 这也使得它可以使用
shared
或更多道具进行扩展。
- 您不必复制索引
- 更改可见性时不必移动文档
关于 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
字符串或数组(用于多用户访问)
然后您可以编写安全规则来检查属性 visibility
和 userid
。
查看 firestore 文档中的示例。
额外内容
- 这也使得它可以使用
shared
或更多道具进行扩展。 - 您不必复制索引
- 更改可见性时不必移动文档