-
Notifications
You must be signed in to change notification settings - Fork 974
Description
Operating System
macOS Ventura 13.4, Darwin 24.4.0
Environment (if applicable)
Node.js v20.18.0
Firebase SDK Version
12.0.0
Firebase SDK Product(s)
Database
Project Tooling
TypeScript, Jest testing framework
Detailed Problem Description
When using Firebase Realtime Database with orderByChild()
queries, calling snapshot.forEach()
on snapshots received from child_added
events throws an error: "No index defined for <key>"
. This occurs even when the database is offline or when proper indexes are defined in security rules.
What I was trying to achieve:
- Listen for
child_added
events on a query ordered by a child field - Iterate through the snapshot's children using
snapshot.forEach()
What actually happened:
- The
child_added
event fires correctly and the snapshot contains the expected data - Calling
snapshot.forEach()
throws:Error: No index defined for createdAt
- The same
forEach()
call works perfectly when called on a fresh snapshot obtained viaget(snapshot.ref)
Error message:
BUG: No index defined for createdAt
Steps and code to reproduce issue
import { initializeApp } from "firebase/app";
import {
getDatabase,
ref,
set,
get,
query,
orderByChild,
onChildAdded,
goOffline,
} from "firebase/database";
const app = initializeApp({
databaseURL: "https://test-bug-repro.firebaseio.com",
}, "bug-repro-modern");
const db = getDatabase(app);
goOffline(db);
const testData = {
items: {
item1: {
createdAt: 1741445778252,
},
},
};
async function reproduceOrderByChildForEachBug() {
set(ref(db), testData);
const itemsRef = ref(db, "items");
const q = query(itemsRef, orderByChild("createdAt"));
onChildAdded(q, async (snapshot) => {
console.log(`Received onChildAdded for: ${snapshot.key}`);
// This forEach call fails
try {
snapshot.forEach((child) => {
console.log(`Child: ${child.key}`);
return undefined;
});
} catch (error) {
console.error(`BUG: ${error.message}`); // "No index defined for createdAt"
}
// This workaround works
const freshSnapshot = await get(snapshot.ref);
freshSnapshot.forEach((child) => {
console.log(`Child (fresh): ${child.key}`);
return undefined;
});
});
}
reproduceOrderByChildForEachBug();
Expected vs Actual Behavior
Expected behavior: snapshot.forEach()
should work on snapshots from child_added
events just as it works on fresh snapshots.
Actual behavior: snapshot.forEach()
throws an index error on snapshots from child_added
events, requiring a workaround of fetching a fresh snapshot first.
Workaround
The current workaround is to fetch a fresh snapshot before calling forEach()
:
// Instead of calling forEach directly on the child_added snapshot:
// snapshot.forEach(callback); // ❌ Fails
// Use this workaround:
const freshSnapshot = await get(snapshot.ref);
freshSnapshot.forEach(callback); // ✅ Works