Ahmad Alghawi

2026-04-30 · 1 min read

The Firestore orderBy + where Composite Index Pitfall

A "simple" published-posts query exploded in production with a missing-index error. Here is why, and the two-line fix that made it go away.

firebase · firestore · performance

The query that broke production

const q = query(
  collection(db, 'posts'),
  where('published', '==', true),
  orderBy('publishedAt', 'desc'),
);

Looks innocent. It works in the emulator. It works locally with one or two documents. Then you deploy and your users see a console full of:

The query requires an index. You can create it here: …

Why?

Firestore needs a composite index for any query that combines a where filter with an orderBy on a different field. Single-field indexes are automatic; composite ones are not.

Two ways to fix it

Option A — create the index. Click the link in the error, wait a few minutes, done. This is the right answer for large collections.

Option B — sort client-side. For small datasets (a personal blog, a CV page, a portfolio with twenty entries) this is simpler:

export async function getPublishedPosts(): Promise<Post[]> {
  const q = query(collection(db, 'posts'), where('published', '==', true));
  const snap = await getDocs(q);
  return snap.docs
    .map((d) => serializeDoc<Post>(d.id, d.data()))
    .sort((a, b) => (b.publishedAt ?? '').localeCompare(a.publishedAt ?? ''));
}

No index management, no migration, no surprise billing.

Rule of thumb

If your collection will never grow past a few hundred documents and you already have to download all of them to render the page, sort in JS. Save composite indexes for the queries that genuinely need them.