Firestore 规则 |仅在提供文档 ID 时才允许获取文档
Firestore rules | Allow to get docs only if doc ids is provided
我根据 ID 列表获取我的文档。
db.collection("fruits").where(db.FieldPath.documentId(), "in", fruitIds).get()
我应该如何编写我的安全规则来允许上面的调用并拒绝下面的调用
db.collection("fruits").get()
不可能完全按照您的要求。你可以做的是像这样设置你的规则:
match /fruits/{id} {
allow get: true;
allow list: false;
}
这允许客户在知道 ID 的情况下获取文档,但无法批量查询文档。
然后,您必须使用 DocumentReference get()
(而不是带有 where 子句的查询)对您的客户端应用程序请求每个文档进行编码。这对性能的影响可以忽略不计(不,按照您在此处显示的方式使用“in”查询没有任何明显的性能提升 - 而且您每批只能处理 10 个文档)。
作为@Doug covered in ,目前不支持您期望的方式。
但是,通过查看 reference,您至少可以通过对任何使用的 orderBy
和 limit
设置条件来限制 list
(查询)操作查询使其变得更加困难而不是完全阻止它。
考虑一下这个回答很有教育意义,只需获取项目 one-by-one 并在您的安全规则中禁用 list/query 访问。它包含在这里是为了那些只想混淆而不是完全阻止此类查询的人。
这意味着将您的查询更改为:
db.collection("fruits")
.where(db.FieldPath.documentId(), "in", fruitIds)
.orderBy(db.FieldPath.documentId()) // probably implicitly added by the where() above, but put here for good measure
.limit(10) // this limit applies to `in` operations anyway, but for this to work needs to be added
.get()
service cloud.firestore {
match /databases/{database}/documents {
// Matches any document in the cities collection as well as any document
// in a subcollection.
match /fruits/{fruit} {
allow read: if <condition>
// Limit documents per request to 10 and only if they provide an orderBy clause
allow list: if <condition>
&& request.query.limit <= 10
&& request.query.orderBy = "__name asc" // __name is FieldPath.documentId()
allow write: if <condition>;
}
}
}
使用这些限制,这应该不再有效:
db.collection("fruits").get()
但您仍然可以使用以下方法以更小的块抓取所有内容:
const fruits = [];
const baseQuery = db.collection("fruits")
.orderBy(db.FieldPath.documentId())
.limit(10);
while (true) {
const snapshot = await (fruits.length > 0
? baseQuery.startAt(fruits[fruits.length-1]).get()
: baseQuery.get())
Array.prototype.push.apply(fruits, snapshot.docs);
if (snapshot.empty) {
break;
}
}
// here, fruits now contains all snapshots in the collection
我根据 ID 列表获取我的文档。
db.collection("fruits").where(db.FieldPath.documentId(), "in", fruitIds).get()
我应该如何编写我的安全规则来允许上面的调用并拒绝下面的调用
db.collection("fruits").get()
不可能完全按照您的要求。你可以做的是像这样设置你的规则:
match /fruits/{id} {
allow get: true;
allow list: false;
}
这允许客户在知道 ID 的情况下获取文档,但无法批量查询文档。
然后,您必须使用 DocumentReference get()
(而不是带有 where 子句的查询)对您的客户端应用程序请求每个文档进行编码。这对性能的影响可以忽略不计(不,按照您在此处显示的方式使用“in”查询没有任何明显的性能提升 - 而且您每批只能处理 10 个文档)。
作为@Doug covered in
但是,通过查看 reference,您至少可以通过对任何使用的 orderBy
和 limit
设置条件来限制 list
(查询)操作查询使其变得更加困难而不是完全阻止它。
考虑一下这个回答很有教育意义,只需获取项目 one-by-one 并在您的安全规则中禁用 list/query 访问。它包含在这里是为了那些只想混淆而不是完全阻止此类查询的人。
这意味着将您的查询更改为:
db.collection("fruits")
.where(db.FieldPath.documentId(), "in", fruitIds)
.orderBy(db.FieldPath.documentId()) // probably implicitly added by the where() above, but put here for good measure
.limit(10) // this limit applies to `in` operations anyway, but for this to work needs to be added
.get()
service cloud.firestore {
match /databases/{database}/documents {
// Matches any document in the cities collection as well as any document
// in a subcollection.
match /fruits/{fruit} {
allow read: if <condition>
// Limit documents per request to 10 and only if they provide an orderBy clause
allow list: if <condition>
&& request.query.limit <= 10
&& request.query.orderBy = "__name asc" // __name is FieldPath.documentId()
allow write: if <condition>;
}
}
}
使用这些限制,这应该不再有效:
db.collection("fruits").get()
但您仍然可以使用以下方法以更小的块抓取所有内容:
const fruits = [];
const baseQuery = db.collection("fruits")
.orderBy(db.FieldPath.documentId())
.limit(10);
while (true) {
const snapshot = await (fruits.length > 0
? baseQuery.startAt(fruits[fruits.length-1]).get()
: baseQuery.get())
Array.prototype.push.apply(fruits, snapshot.docs);
if (snapshot.empty) {
break;
}
}
// here, fruits now contains all snapshots in the collection