1

enter image description here

This is how my Firestore look like. I am trying to query the 'chatIds' collection to get the 'chatId' containing the two users

 final userIds = [
              '${firebaseAuth.currentUser!.uid}',
              '${user.id}',
            ];

StreamBuilder(
              stream: chatIdRef
                        .where("users", isEqualTo: userIds)
                        .snapshots(),
                    builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
                      if (snapshot.hasData) {
                        var snap = snapshot.data;
                        List docs = snap!.docs;
                        print(docs.length.toString());
                        print(snapshot.data!.docs.toString());
                        return docs.isEmpty
                            ? IconButton(
                                onPressed: () {
                                  widget.isMe
                                      ? Navigate.pushPage(
                                          context, EditProfile(user: user))
                                      : Navigate.pushPage(
                                          context,
                                          Conversation(
                                            userId: user.id!,
                                            chatId: 'newChat',
                                          ),
                                        );
                                },
                                icon: widget.isMe
                                    ? Icon(Ionicons.create_outline)
                                    : Icon(Ionicons.chatbox_ellipses_outline),
                              )
                            : IconButton(
                                onPressed: () {
                                  QueryDocumentSnapshot doc = docs[0];
                                  widget.isMe
                                      ? Navigate.pushPage(
                                          context, EditProfile(user: user))
                                      : Navigate.pushPage(
                                          context,
                                          Conversation(
                                            userId: user.id!,
                                            chatId:
                                                doc.get('chatId').toString(),
                                          ),
                                        );
                                },
                                icon: widget.isMe
                                    ? Icon(Ionicons.create_outline)
                                    : Icon(Ionicons.chatbox_ellipses_outline),
                              );
                      } else {
                        return IconButton(
                          onPressed: () {
                            widget.isMe
                                ? Navigate.pushPage(
                                    context, EditProfile(user: user))
                                : Navigate.pushPage(
                                    context,
                                    Conversation(
                                      userId: user.id!,
                                      chatId: 'newChat',
                                    ),
                                  );
                          },
                          icon: widget.isMe
                              ? Icon(Ionicons.create_outline)
                              : Icon(Ionicons.chatbox_ellipses_outline),
                        );
                      }
                    },
                  ),

The code above works partially, sometimes it doesn't return the chatId until I swap the usersIds i.e instead of doing this:

    final userIds = [
                  '${firebaseAuth.currentUser!.uid}',
                  '${user.id}',
                ];

I do this:

final userIds = [
          '${user.id}',
          '${firebaseAuth.currentUser!.uid}',
        ];

My question is this, Is there a way I can query the chatIds collection to get the documents containing the 2 userIds I supplied?

CharlyKeleb
  • 587
  • 4
  • 17
  • 2
    Simplify the question and add the code of the query and only the important parts, also avoid using code images and paste the code snippet here – Moaz El-sawaf Jun 11 '22 at 09:58
  • To fetch list from firestore use:List listUsers = List.from(snapshot.data!['users']) – raghav042 Jun 11 '22 at 10:34
  • 1
    Suggestion - instead of StreamBuilder(...) use StreamBuilder(...) . is this snapshot of groupchat then okay else may be there's no need to store two userId in list becaue one is always current userId. – raghav042 Jun 11 '22 at 10:47

1 Answers1

1

Since you're comparing the entire array field, Firestore will serialize the field from the document and the value you specify and compare those two with each other.

What you'd really want to do here is use two array-contains clauses, one for each of the UID values, but that also isn't possible.

If you always add all values to your users field in one go, consider adding them in a predefined order. For example, when I need to have multiple UIDs I typically add them in lexicographical order. Once you ensure the ordering in the array field and in the array value you pass are the same, the query will always succeed.

Alternatively you can then also add a field where you store the concatenated UIDs as a single string value. Here too you'd have to ensure that their order is predictable, but then you'd essentially have the same approach that I describe here for the Realtime Database: Best way to manage Chat channels in Firebase

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • String getChatId(String user1, String user2) { user1 = user1.substring(0, 5); user2 = user2.substring(0, 5); List list = [user1, user2]; list.sort(); _chatId = '${list[0]}-${list[1]}'; return _chatId; } // this worked for me – CharlyKeleb Jun 20 '22 at 21:23