0
votes

I'm implementing chat using Firestore. Here is the structure of Firestore:

|- Chats (collection)
|-- AutoID (document)
|--- user1ID (String)
|--- user2ID (String)
|--- thread (collection)
... and then thread has further fields.

In order to get chat between two users I'm fetching it like:

let db = Firestore.firestore().collection("Chats")
    .whereField("user1ID", isEqualTo: Auth.auth().currentUser?.uid!)
    .whereField("user2ID", isEqualTo: user2UID!)

It works fine if user 1 is the current user otherwise if I open chat from other account and current user is user 2 it doesn't fetch this document.

Upon searching I found that I can user arrayContains. So I made an array instead called users and in it I've added both these IDs. So now the structure is: |- Chats (collection)
|-- AutoID (document)
|--- users (Array)
|---- 0: user1ID (String)
|---- 1: user2ID (String)
|--- thread (collection)
... and then thread has further fields.

But when I do:

let db2 = Firestore.firestore().collection("Chats")
    .whereField("users", arrayContains: Auth.auth().currentUser?.uid!)
    .whereField("users", arrayContains: user2UID!)

It's going to fetch the first document it found that has currentUser.uid (Haven't tested it, I'm saying this based on the documentation I've read).

So, how can I get this chat, if an array contains both id's?

2
There are a couple of good answers but my question is, what does get chat between two users mean? In other words, at what point in time would you get the chat between two users - do both users get it? Or just one or the other? When does it happen - when they first authenticate or at some time thereafter. Do they click a 'get my chats' button or perhaps the chats they are involved in are provided in a tableView? Is it just two people in a chat or more than two? There may be additional options with more information.Jay

2 Answers

2
votes

Firstly, the document you outlined doesn't have any array type fields, so arrayContains isn't going to be helpful. arrayContains only matches items of a field that contains an array.

For your current document structure, a single query will not be able to get all the documents between both users, since Cloud Firestore doesn't offer any logical OR type queries. You are going to need two queries: one for getting all documents where user1 is the current user, and one for where user2 is the current user. Then you can merge the results of those two queries in the client code to build the entire list.

1
votes

What I typically do is to name the document for the two users that are having the chat. That way you don't need to do a query to find the document, but can just directly access is based on the UIDs.

To ensure the order in which the UIDs are specified doesn't matter, I then add them in lexicographical order. For an example of this, see my answer here: Best way to manage Chat channels in Firebase