Search code examples
node.jsfirebase-realtime-databasefirebase-admin

Realtime database - orderByChild() works with once(), doesn't work with get()


I have a database with following rules:

{
  "rules": {
    "users": {
      ".read": "auth.uid != null",
      ".indexOn": ["time", "timestamp"],
      "$uid": {
        ".write": "$uid === auth.uid",
      }
    }
  }
}

and data with format

users
  |_ uid
      |_ time
      |_ timestamp

When I perform a query (with Cloud Functions) using once() it works perfectly fine

await admin.database().ref("users").orderByChild("timestamp")
  .once("value", (snapshot) => {
    snapshot.forEach((childSnapshot) => {
      functions.logger.log(childSnapshot.key);
    });
  });

but when I perform query with get()

await admin.database().ref("users").orderByChild("timestamp")
  .get()
  .then((snapshot) => {
    snapshot.forEach((childSnapshot) => {
      functions.logger.log(childSnapshot.key);
    });
  });

I get following error:

Error: No index defined for timestamp at IndexMap.get

Note that it's not the same error when index is not defined at all - in such situation error looks like this:

Error: Index not defined, add ".indexOn": "timestamp", for path "/users"

I was adding new entries after defining index, so all the data should be indexed (in theory). Of course I could just use once() but now I don't know whether my data is being actually indexed or not. Could anybody shed some light on this?


Solution

  • firebaser here

    This is a known issue in the JavaScript SDK, that seems to also surface in the Admin SDK for Node.js. As far as I know there is no fix yet, but the workaround with once() is indeed valid. If I know more about a fix for the issue, I'll post it here.