Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

170
Views
Firestore rules | Allow to get docs only if doc ids is provided

Im getting my documents based on a list of ids.

db.collection("fruits").where(db.FieldPath.documentId(), "in", fruitIds).get()

How should I write my security rules to allow the above call and to deny the below call

db.collection("fruits").get()
about 4 years ago · Juan Pablo Isaza
2 answers
Answer question

0

It's not possible exactly as you require. What you can do is set your rules like this:

match /fruits/{id} {
  allow get: true;
  allow list: false;
}

This allows clients to get a document if they know the ID, but make it impossible to query documents in bulk.

You will have to then code your client app request each document individually with a DocumentReference get() (instead of a Query with a where clause). The performance hit for this is negligible (no, there is not any noticeable performance gain for using an "in" query the way that you show here - and you are limited to 10 documents per batch anyway).

about 4 years ago · Juan Pablo Isaza Report

0

As @Doug covered in their answer, this is not currently supported in the way you expect.

However, by looking at the reference, you can at least limit list (query) operations by placing conditions on the orderBy and limit used by any queries to make it more difficult rather than outright blocking it.

Consider this answer educational, just fetch the items one-by-one instead and disable list/query access in your security rules. It is included here for those who simply want to obfuscate rather than outright block such queries.

This would mean changing your query to:

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>;
    }
  }
}

Using those restrictions, this should no longer work:

db.collection("fruits").get()

But you could still scrape everything in smaller chunks using:

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
about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!