1

I'm trying to figure out how to mimic querying by value with an array, but having issues as the data loses its ordering if each query by value is done individually.

Let's say the database has the following format:

  • postID
    • userID
    • datePosted

And on the client side, I have an array of userIDs: [id1, id2, id3]

I want to sort postID's by datePosted, query by value where the userID equals one of the id's in the array. I then want to query the first 5 posts. So, this should get a total of at most 5 of the most recent posts from those users.

I've read that you are not able to query by value with an array, meaning this would have to be separated into single queries for each userID (such as firebase equivalent to sql where in () suggests). However, if I were to do that, I'd no longer be able to correctly sort by datePosted between posts from different users and would have to download ALL posts to be able to sort and get the first 5.

In essence, I'm trying to accomplish: ref.queryOrderedByChild("datePosted").queryEqualToValue(array, "userID").queryLimitedToFirst(5)

Anyone ran into this kind of problem before? Would appreciate any suggestions!

Community
  • 1
  • 1
Flyte27
  • 53
  • 9

1 Answers1

1

I assume you're trying to model something like a social network, where you show the posts from people that a user follows. If that is the case, let's call that thing the "wall".

One way you could model this:

posts
  -Kjas0273471234
    title: "Alternatives to Firebase query by value with arrays"
    body: "..."
    uid: "Flyte27"
    timestamp: 1455655809614
  -Kjas0281386734
    title: "An interesting data model"
    body: "..."
    uid: "puf"
    timestamp: 1455655909614
walls
  Flyte27
    -Kjas0273471234: 1455655809614
    -Kjas0281386734: 1455655909614

So in this model, your wall has the keys of posts of people you follow. I set the value to the timestamp, since you might want to order by that.

Now with this structure you can query and show the posts with:

ref.child('walls').child(auth.uid).orderByValue().on('value', function(keys) {
  keys.forEach(function(keySnapshot) {
    ref.child('posts').child(keySnapshot.key()).once('value', function(postSnapshot) {
      console.log(postSnapshot.val());
    });
  });
});
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Yea, denormalizing the data is definitely one solution, it just seems like with a social media style application where a user potentially has hundreds of friends, this would lead to a HUGE amount of duplication on the backend as number of users scales. Though there's no better alternative I suppose? Still getting used to how Firebase works. – Flyte27 Feb 16 '16 at 21:04
  • Duplication of data for faster reads. Sounds like a classical space vs time tradeoff. It's called fanout and it's pretty common in NoSQL: http://highscalability.com/blog/2013/7/8/the-architecture-twitter-uses-to-deal-with-150m-active-users.html. – Frank van Puffelen Feb 16 '16 at 21:12
  • True. I'm a bit worried about space scalability, but it seems like that's the best way to go. Thanks for the answer! – Flyte27 Feb 16 '16 at 21:30