Home > Net >  multiple "==" operator in firebase for same the field
multiple "==" operator in firebase for same the field

Time:11-25

I know the title sounds like I should go with the in operator. But this would be the case if firebase had no limitation for more than one in on a single query.

I'm working on a simple one-to-one messaging web app with a collection for all my chats. Each document there represents one single message. Here's the structure of my data in one document

{
  "content": "hello",
  "sender": "sender ID",
  "receiver": "receiver ID",
  "timestamp": "SOME TIMESTAMP"
}

So I want to retrieve all the documents where I'm (the logged-in user) the sender or receiver, AND my currently opened chat is the sender or receiver

I don't know if I made it clear. If firebase would permit two in on a single query, my goal above could be achieved by:-

query(
      chatsRef,
      where("sender", "in", [myID, partnerID]),
      where("receiver", "in", [myID, partnerID]),
      orderBy("timestamp")
    )

In MySQL, the code will look like this:

SELECT * FROM messages
    WHERE (sender = {$myID} AND receiver = {$partnerID})
    OR (sender = {$partnerID} AND receiver = {$myID}) ORDER BY timestamp)

Firebase claims the in operator to be the logical OR and not-in to be the logical AND but doesn't let us combine them in a single query, which is quite weird from my pov

However, I've tried combining multiple == operators for the same field in a single query, but this one also doesn't work. Here's the code below:

query(
      chatsRef,
      where("sender", "==", myID),
      where("receiver", "==", partnerID),
      where("sender", "==", partnerID),
      where("receiver", "==", myID),
      orderBy("timestamp")
    )

So I would appreciate it if anyone could come up with any solution. Even if it takes to re-structure my data (as long as it doesn't overflow my single doc size and I can use firebase's snapshot function efficiently enough)

[NOTE: I'm using ReactJS; in case it matters]

CodePudding user response:

Your SQL query performs an OR condition across multiple fields, which is currently not possible in Firestore. So there's no way to map that query to Firestore as is.

The in mapping (even if Firestore did allow in on two fields) is not the same, as it also allows combinations that your SQL doesn't: sender == {$myID} AND receiver == {$myID} and sender == {$partnerID} AND receiver == {$partnerID}.

Your last query performs and AND across all conditions, which will never match any results because a single field can never equality match two different values at the same time.


What I usually do is to add an extra field to the document with the UIDs of the participants in a reliable order (i.e. alphabetically). E.g. if we were the participants and our UIDs were Pratik and Frank:

participantsUIDs: "Frank_Pratik"

The order if the UIDs in this field is alphabetical, so no matter who sent the message and who received it, the value would always be the same.

So unlike the sender and receiver fields this loses knowledge of the participants roles, but it does then put them in a predictable order, which means that you can query for documents with two specific participants reliably too.


You can also use an array field for the participants, as long as you ensure the items are in a predictable order too:

participants: ["Frank", "Pratik"]

On such a field you can use an == operator too, as long as you pass in the exact same values in the same order.

  • Related