Firestore's orderBy doesn't sort your data β it silently deletes some of it
Abbas
May 24, 2026
Some recipes stopped showing up on Bano's Cookbook. Not all of them. Not none of them. Some.
The query returned 200 OK and a list. It just wasn't the whole list β and nothing anywhere said so.
The change that caused it
At some point the recipes query grew an ordering clause, which is the most natural thing in the world to write:
const snap = await db
.collection('recipes')
.orderBy('createdAt', 'desc')
.get();
The collection had been accumulating documents for months before createdAt was introduced. Those older documents simply don't have the field.
Why they vanish rather than sort last
This is the part worth internalising, because the intuition is wrong.
An ordered Firestore query is served from an index, not by fetching everything and sorting it. A document that has no value for the ordered field has no entry in that index. It is not sorted to the end, and it is not returned unordered. It is not in the index, so it cannot come back.
The query is behaving exactly as designed. It is just that "give me these documents, ordered" quietly means "give me the documents that can be ordered."
Why this is worse than a crash
A hard failure gets noticed in minutes. This failure returns a page that renders perfectly, with a list that looks complete unless you happen to know what should be on it. Partial results look exactly like working software.
This is the whole class of bug: an error would have been kinder than a success.
The fix
Drop the ordering from the query and sort in application code, so membership never depends on the index:
const snap = await db.collection('recipes').get();
const recipes = snap.docs
.map(mapDoc)
.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
Seventeen lines changed. Every recipe came back.
The trade-off is real and you should make it deliberately: you are now paying to read the whole collection and sorting in memory, which is fine at a few hundred documents and wrong at a hundred thousand. The alternative β and the right answer at scale β is a backfill that writes createdAt to every legacy document so the index is complete, then restoring the ordered query.
The general rule
Adding orderBy to an existing collection is a migration, not a query change. Before you ship one, ask what fraction of the collection predates the field you're ordering by. If the answer isn't "zero", you're about to hide data from yourself.
And more broadly: be suspicious of anything that can return fewer results without returning an error. Those are the bugs that live in production for months.
Commit 1faddd3 in Bano's Cookbook.