Search code examples
swiftfirebasedata-structuresfirebase-realtime-databasesnapchat

Structuring Firebase database like Snapchat


I've been working on a snapchat clone as a way to learn how to use firebase.

I am currently stuck on how to best structure my data so that I could mimic a simple version of Snapchat.

What I'd like to do in my simplified version:

  1. Send a picture message to multiple users
  2. Post the picture message to a "story" feed where all my friends can see it.

I don't need anything more really. I'm not trying to implement snapchats current feature of being able to send text messages or anything like that. I just want to send pictures to friends and also post them to a public feed.

I've structured my data like this:

overall DB structure

And Breaking it down:

Users:

users

Friendships between users structured like this:

Friendships

Individual messages structured like this:

messages

An index for conversations like this:

enter image description here

Now I've seen plenty of posts on stack and online for structuring messages in chat applications. What I'm stuck on is how to structure my DB so that a message can be sent to a user so that only that users receiving users see it.

I've been reading the firebase docs and I know I should be denormalizing data so that I can read data more efficiently, but I can't really wrap my head around the best way to do so with Firebase.

In my current implementation of user-messages, I would have to implement a check in my code to see if the message was sent by my user, and then prevent the user from seeing it. Ideally only the person who the message was sent to should see the image. (just like snapchat)

Any suggestions on how to do so?

Do I need to have some reference to the chat/message in the user tree?


Solution

  • The question appears to be

    how to structure my DB so that a message can be sent to a user so that only that users receiving users see it

    There are many 'directions' but here are two.

    1) Manually 'tell' each user about a pic

    users
      uid_0
        pics_for_me
          pic_0
            url: "http://...."
          pic_1
            url: "http://...."
        my_users
          uid_2: true
      uid_1
        pics_for_me
        my_users
          uid_0: true
          uid_2: true
    

    With this structure, uid_1 has two users they want to share pics with (uid_0 and uid_2) so when it comes time to share the pic, read the my_users node, iterate over it, and store a link to the pic in that users respective pics_for_me node. Obviously you could store other data such as who it's from etc. When uid_0 logs in, read the pic_for_me node and view the pics, perhaps deleting it when done.

    2) Observe a node for pics for a user

    users
      uid_0
        name: "Henry"
      uid_1
        name: "Joe"
    
    all_pics
      pic_0
       for_user: "uid_0"
       url: "http://..."
    

    in this scenario, uid_0 logs on and adds a query to all_pics for any for_user that contains their user id. This would work for a 1-1 situation where the pic is meant for one user. If you want multiple users to get a pic then...

    all_pics
      pic_0
        uid_0: true
        uid_1: true
    

    and when a user logs in add a query to all_pics where that users uid is true, and then any time a picture is added that has a child of their uid, they will receive an event.