3

We have just started exploring firebase for our new app. The app basically needs chat between users and Group chat.

For the chat application we are creating: MessageThread(id, User:userA, User:userB, UserGroup:group, Array:deletedBy, ...)

The main problem is firebase doesn't support OR queries and IN queries, which I need in my use-case. For example:

Dummy query to access user's conversations list: fetch MessageThread(s) where (currentUser.id==userA.id) OR (currentUser.id==userB.id) OR (currentUser.id IN group.members)

I am missing something to understand Firebase? What is the other alternative way to design our database to solve this problem?

Community
  • 1
  • 1
iMemon
  • 1,095
  • 1
  • 12
  • 21

1 Answers1

3

In NoSQL you will have to model the data for the way your app wants to use it. So if you need a list of the conversations that the user is part of, you should keep that list in your database:

/conversationMessages
    $conversationId
        $messageId
            text: "Hello world"
            sender: "uid of sender"
            name: "name of sender"
/userConversations
   $uid
     $conversationId1: true
     $conversationId2: true

With this you can easily look up the list of conversations that each user is a part of and then load the messages for one of them. You'll probably also want to keep a separate list of the metadata for each conversation:

/conversationMetadata
    $conversationId
        lastUpdated: timestamp (set with ServerValue.TIMESTAMP)
        title: "name of our chat room"

That way you can show the list of conversations for a user by loading their conversation ids and then loading the metadata of each conversation:

var ref = database.ref().child("userConversations").child(auth.uid);
ref.on('child_added', function(conversationKey) {
    var conversationRef = database.ref().child("conversationMetadata").child(conversationKey.key);
    conversationRef.once('value', function(metadataSnapshot) {
      console.log(metadataSnapshot.val());
    });
});

Trying to map SQL knowledge onto a NoSQL database leads to a difficult learning experience. I highly recommend reading the relevant section of the Firebase documentation and this article about NoSQL data modeling.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Thank you, one more question: Is there any support of making references in firebase? For example: I want to save user's object in conversation, so that I can show user's name and photo on the conversation list screen. – iMemon Jun 19 '16 at 20:43
  • There are no managed foreign key references. But it's very common to have (unmanaged) references. See the section of the documentation on [creating data that scales](https://firebase.google.com/docs/database/android/structure-data#fanout). – Frank van Puffelen Jun 19 '16 at 22:26
  • In my senerio, I have group/user chat and chat name & image is fetched from that group/user And I can't denormalize it because user has the option to change it anytime. So from your mentioned approach, I can have a table /conversationMetadata where I will a reference of user/group. Now the problem is for fetching a conversation list (as explained in your mentioned above code): First I am fetching userConversations then I am fetching conversationMetadata for every conversation and then I need to fetch userData or groupData (to get name/image). Don't u think it will be too slow? Please help. – iMemon Jun 21 '16 at 01:40
  • 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 Jun 21 '16 at 02:10