1

I have the following structure in Firebase database:

root
 - Users
 - Posts
   - -K_54s1smPPh6qN4znuT
     - key1: val
     - key2: val
     - User:
       - -K_54sSomeKeyFromUsersObject: "John Doe"
...

But I can't find any example in documentation how can I fetch all Posts by UserKey when I have structure like this.

I need help on how to make a query to compare nested data like this?

2 Answers 2

1

One way to approach this is to save the reference to the posts on the user. Like this:

root
 - Users
   - [UserID]
      - UserPosts
        -K_54s1smPPh6qN4znuT
 - Posts
   - -K_54s1smPPh6qN4znuT
     - key1: val
     - key2: val
     - User:
       - -K_54sSomeKeyFromUsersObject: "John Doe"
...

So when you want to retrieve all posts by an user, you just look at the references on the user profile

Sign up to request clarification or add additional context in comments.

4 Comments

So when I got all keys from user object this means that I need to make another request to get all posts from Posts right?
Yes, but you can limit the number of posts. Getting 10 references to posts and using a pagenation if the user wants more, is a good solution
Ok, just one last subquestion... in firebase I can make a query where I can pass list of key that I want to get back... like in SQL WHERE Posts.ID in (k1, k2, k3...)?
I think there are several good examples on these two videos. I think the second video answers your question, but watch both since they are very easy to follow: #1: youtube.com/watch?v=sKFLI5FOOHs and #2: youtube.com/watch?v=Idu9EJPSxiY
0
+100

I would suggest an alternative

users
  uid_0
    name: "Frank"
  uid_1
    name: "Biff"

posts
  post_0
    msg: "some post"
    user_id: "uid_0"
  post_1
    msg: "Another post"
    user_id: "uid_1"

then a simple query will return all of uid_0's posts

let postsRef = root.child("posts")

postsRef.queryOrdered(byChild: "user_id").queryEqual(toValue: "uid_0")
        .observeSingleEvent(of: .value, with: { snapshot in
    print(snapshot)  //prints all of uid_0's posts
})

This avoids the need to gather up the post id's and then try to perform a SQL-like query WHERE Posts.ID in (k1, k2, k3...) as Firebase doesn't offer a query like that directly.

In response to a follow up comment about how to handle when a single post has multiple users...

posts
  post_0
    msg: "some post"
    users:
      uid_0: true
      uid_1: true
  post_1
    msg: "Another post"
    users:
      uid_1: true
      uid_2: true

The code to get the nodes that contain uid_1: true is similar and called a deep query or deep paths. That's an older post but will give you really good information.

let postsRef = root.child("posts")

postsRef.queryOrdered(byChild: "users/uid_1").queryEqual(toValue: true)
        .observeSingleEvent(of: .value, with: { snapshot in
    print(snapshot)  //prints all of uid_0's posts
})

9 Comments

Hi, thanks but how can I apply this design when Posts can have multiple users on it. One post must have a list of users in it. That is why I created Users child it is a list.
@1110 I assume you mean that Posts can have multiple users watching the post? If so, I updated my answer to handle that. There's nothing wrong with the accepted answer, I just wanted to provide an alternative.
I like more this approach but it simply doesn't work. Snapshot is always null.
Based on second design you added (after comment) how to write a query to return all posts for 'uid_1'?
This return me null: ref.child("posts").child("users").queryOrdered(byChild: "-KXFrbzxUwaBGjtmjfGr") .observeSingleEvent(of: .value, with: { snapshot in print(snapshot) })
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.