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,您至少可以通过对任何使用的 orderBylimit 设置条件来限制 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