Short answer
Split the ids into groups of 30, run one query per group in parallel, and merge the results. Combining two in filters, or in with or, multiplies the count, so keep the total under 30. For long lists, store a field you can query with one equality filter instead.
Rather not fix it yourself? App Fix Ticket starts with a fixed-price diagnosis, then a fixed price for the fix before any fix work.
Why the query fails, and the fix
01
The list has more than 30 values
“Use the in operator to combine up to 30 equality (==) clauses on the same field with a logical OR.” Firebase, Simple and compound queries (in)
An in filter on a list of ids, such as the people a user follows, works until the list passes 30. Split it and query each part.
// Web SDK import { collection, query, where, getDocs, documentId } from 'firebase/firestore'; const unique = [...new Set(ids)]; const chunks = []; for (let i = 0; i < unique.length; i += 30) chunks.push(unique.slice(i, i + 30)); const snaps = await Promise.all( chunks.map((c) => getDocs(query(collection(db, 'users'), where(documentId(), 'in', c)))), ); const users = snaps.flatMap((s) => s.docs.map((d) => ({ id: d.id, ...d.data() })));02
Two filters multiply the count
“These queries are limited to 30 disjunctions based on the query's disjunctive normal form. This limit is fixed and cannot be adjusted.” Firebase, Simple and compound queries (Limitations)
Firestore counts the or, in and array-contains-any parts together. Two in filters with 6 values each make 36 combinations, which is over the limit even though each list is short. If the query has another in or or, divide 30 by that part’s size to get the chunk size.
03
not-in has a lower limit
“not-in supports up to 10 comparison values.” Firebase, Simple and compound queries (Limitations)
not-in allows only 10 values. To hide more, filter them out in the app after the query, or store a flag on the documents and filter on that.
04
The query shape doesn’t fit the data
If a screen always needs hundreds of ids, change the data instead: store the owner or group id on each document and query it with one == filter, or keep a list on a single document. On a server, the Admin SDK getAll() reads many known documents in one call. Chunked reads still cost one read per document.
Checked against the vendor’s docs on : Firebase docs: Simple and compound queries.
Rather hand it over?
Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.
- from $450App Fix TicketOne reproducible bug in an existing mobile or web app, diagnosed and fixed.See scope and start
- from $450AI-Built App RescueA Lovable, Bolt or Cursor app checked end to end in 3 days, then its worst problems fixed at a fixed price.No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.See scope and start
“Very responsive, attentive to fixing bugs, and completed the project as needed! Thank you!”
Related: Firestore query requires an index · Firestore quota exceeded · Firestore invalid document reference · Cloud Firestore API disabled