0

With a structure of

/archive: {
  $userId: {
    $archiveKey: {
      foo: 1
    },
    ...
  },
  ...
}

Where $userId references a user id and $archiveKey is dynamic, created by .push().

Is it possible to query the archive ref and get all archiveObjects where foo = 1 ? Or do I need to fetch down the whole table, manually dig into $userId and extract the archiveObjects I'm looking for?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Martol1ni
  • 4,684
  • 2
  • 29
  • 39
  • 1
    There is no standard querying system in Firebase, you need to structure your data in order to be able to do the reads your application needs. So yeah, you need to manually dig or find a data structure that suits your needs – Th0rndike Apr 20 '16 at 10:21
  • AFAIK, that's only partially true. You have deeply nested on static children like `orderByChild('child1/child2')`. My question is whether this is possible to do with dynamic children as well. – Martol1ni Apr 20 '16 at 10:32

1 Answers1

2

Firebase queries can nowadays query nested paths, but the paths cannot be dynamic.

So if you know the uid, you can query that user's archives with:

ref.child(authData.uid).orderByChild('foo').equalTo(1).on(...

If you don't know the uid, then you'll have to create a data structure that allows you to do the lookup:

archive_category_to_uids: {
  foo: {
    1: {
      uid1: true,
      uid2: true
    }
  }
}

A more common way is to separate the archives into their own top-level list and have both users and categories refer to that:

users: {
  userId1: {
    archiveKey1: true,
    ...
  },
  ...
},
archives: {
  archiveKey1: {
    foo: 1,
    uid: uid1
  },
  ...
},
archiveCategories: {
  foo: {
    1: {
      archiveKey1: true,
      archiveKey2: true
    }
  }
}

Now you can get find the archives with:

ref.child('archiveCategories/foo/1').once('value', function(keys) {
  keys.forEach(function(key) {
    ref.child('archives').child(key.key()).once('value', function(snapshot) {
      console.log(snapshot.val());
    });
  };
});

This process is called denormalization and is quite common in NoSQL databases. You're modeling the data for how your application needs to consume it. For more on this and other common patterns, I recommend reading this article on NoSQL data modeling.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • This is very interesting, however on your last query, you're actually doing `number of archives` number of queries, but I guess I would have to time whether that's worth the efficiency of getting down the whole tree and parsing it manually. Thanks alot. – Martol1ni Apr 21 '16 at 09:20
  • The `once()` in that last snippet is not a query. It's a direct lookup, which is very fast. See http://stackoverflow.com/questions/35931526/speed-up-fetching-posts-for-my-social-network-app-by-using-query-instead-of-obse/35932786#35932786 – Frank van Puffelen Apr 21 '16 at 14:21