J.Doe J.Doe - 4 months ago 18
Swift Question

Need guidance on firebase data structure

I've spent a solid 8 hours messing around with different ways to accomplish this and I can't find a way that works well/that makes sense. I think I might be over complicating it. Any help is greatly appreciated.

The general gist is I have an initial tableview that loads posts from all users/ eventually just friends.
Users are able to "join in" on posts by tapping on a specific cell.
Then I need another page that shows a user all of the posts they've joined in on, and then a final page that shows all of the individuals who also joined in on a specific post.

So like a user sees a post about cats, clicks on the post, joins in. goes to another screen and cats will now be in that tableview along with any other posts they joined in on. Click on the cats cell and all the users that joined in on cats.

TableView1 is all posts

TableView2 is posts that user has joined in on

TableView3 is a "detail view" of a selected cell from tableview2 that shows all users that joined in on that post back from TableView1.

I absolutely cannot figure out a good way to structure the data.

A sort of "catch" is that a user can only make 1 post a day, so there are never any duplicates under a user's posts, but I'm so confused I don't even know if that makes a difference.

I basically had something like :

initiatedPosts:
ABC123:
Initiator : userUIDWhoDidIt
text: "talk about cats"
timestamp: 2093840928309482
PostsInResponseToThis:
User: userwhodidit
text: "cats suck"

users:
User1
(general user info)
PostsJoinedInOn
ABC123


And it's just a total hot mess. I've tried so many things I forget what I've tried so a fresh set of eyes on this would be great.

I'm basically needing to :

1) Query back all initiated posts on view1

2) Query back all posts the current user has joined in on on view 2

3) Query back all of the people who have joined in on the selected post from view 2

I know how to run those queries and add it all to the tableviews, I just don't know how to set up my database.

Answer

With Firebase, you should generally aim to flatten your data structure and store keys you can use to locate the data you need from any node. Here's a Bolt schema that should suit all of your use cases.

path /posts/{post_id} is Post {}

path /users/{user_id} is User {}

type PostID extends String {}
type UserID extends String {}

type Post {
  author_id: UserID
  text: String
  timestamp: Number
  reply_post_ids: Map<PostID, Boolean>
}

type User {
  post_ids: Map<PostID, Boolean>
  reply_post_ids: Map<PostID, Boolean>
}

Query back all initiated posts on view1

Simply fetch all the posts at /posts.

2) Query back all posts the current user has joined in on on view 2

Look up each of the posts in /users/{user_id}/post_ids. You could even lookup their replies at /users/{user_id}/reply_post_ids.

3) Query back all of the people who have joined in on the selected post from view 2

For the post, lookup all of the posts through /users/{user_id}/reply_post_ids, and then lookup the users in those posts.

While it might feel like you're making a lot of round trips to Firebase, Firebase will intelligently batch requests as necessary. See this StackOverflow question for details.