2

I want to get message sent from a specific user to another. I am unable to achieve this. When I use the following code, I get the message from receiver. What I need is to get message particular recieverid to particular senderid.

My Database Snapshot

enter image description here

Here is my code:

Database.database().reference().child("chats")
    .queryOrdered(byChild: "receiverid")
        .queryEqual(toValue: "xEdACTcUWeOwrdIqjxeP5t5y4Kg2")
            .observe(.childAdded, with: { snapshot in
                let msgDict = snapshot.value as! [String: Any]
                print(msgDict)
            })
mert dökümcü
  • 761
  • 3
  • 9
  • 31
Vinay
  • 23
  • 4
  • 1
    Firebase Database queries can only order/filter on a single property. You're trying to filter on two properties, which is not possible. But you can combine the two values into a single property and filter on that. In fact, I recommend that you change your data structure to model chat rooms as a layer in your database and use the concatenated user IDs as the name for this room. For an example of this, see http://stackoverflow.com/questions/33540479/best-way-to-manage-chat-channels-in-firebase – Frank van Puffelen Dec 28 '17 at 16:01
  • In what context are you trying to get a message from a particular sender to a particular receiver? i.e. if you are the sender you can query for messages you sent, and if you are the receiver you can query for messages meant for you. Is this an admin thing where you are querying for messages sent from one person to another? What's the use case? – Jay Dec 28 '17 at 22:55

1 Answers1

1

When using Firebase, you should structure your data to match the need of your views.

It looks like what you're trying to do is execute a query based on 2 properties and the Realtime Database can't do that yet. I recommend changing the structure of your data. Use your senderId as the key to each chat. This way you'd have something like this:

"chats"{
    "-L1RW456789":{
        "messageKey":{
        "name":"ddddd",
        "receiverid":"xEdACTcUWeOwrdIqjxeP5t5y4Kg2",
        "sender_id":"-L1RW456789",
        "text":"Hello World"
        },
        "message2Key":{
        "name":"eeeee",
        "receiverid":"xEdAdasd23123",
        "sender_id":"-L1RW456789",
        "text":"How are you?"
        }
    }
}

(You can remove the "sender_id" attribute now, as it is now accessed by getting the key of the message's parent node) And you'd be able to run your query like this:

Database.database().reference().child("chats").child("-L1RW456789")
    .queryOrdered(byChild: "receiverid")
        .queryEqual(toValue: "xEdACTcUWeOwrdIqjxeP5t5y4Kg2")
            .observe(.childAdded, with: { snapshot in
                let msgDict = snapshot.value as! [String: Any]
                print(msgDict)
            })
  • Good try but that won't work as you cannot have duplicate keys. i.e. if the sender sends a message, and then sends another, the second message will overwrite the first message because the keys are the same. However, if the use case is to overwrite messages when they are sent, it will work. – Jay Dec 28 '17 at 22:56
  • Hmm. Now that I am re-reading this you say *Use your senderId as the key to each message* but that's not what your structure is. That structure is the sender key is a parent node and then the children have a key? In that case the sender_id child node is not needed as you already know it because it's the parent node. Perhaps a clarification would help? – Jay Dec 28 '17 at 23:01
  • My bad. I mean't "key to each chat". Edited my answer – Rosário Pereira Fernandes Dec 28 '17 at 23:49
  • Great! A +1 for you. The downside to this structure (and question) is security. It would be impossible to limit access to these nodes i.e. every user would need access to every other users node to do the query. If you wanted to 'lock it down' via rules to only allow queries if the user is an 'admin' type user that would have access. – Jay Dec 29 '17 at 16:02
  • I see. I never built a chat app, but if I ever did I'd probably think of a different (and more secure) structure. But this is my best shot right now. Thank you @Jay – Rosário Pereira Fernandes Dec 29 '17 at 21:52