7

Is it possible to compare two arrays in a Firestore query without 'array-contains'?

Something like this:

    query = query.where(
       "info.currentLocation",
       "==",
       currentUserBasicInfo.currentLocation
    );

info.currentLocation and currentUserBasicInfo.currentLocation are both arrays with mapped values. I can't change the data structure and I already have an 'array-contains' in the query. Because the two arrays have to be identical for this to run, I feel like there has to be a way to compare two arrays without having to use 'array-contains' or 'array-contains-any' or 'IN'.

Any suggestions? Is this possible?

2
  • 1
    I just saw in a comment that you got this to work. Can you post your own answer, as I think this would be really useful for others? Commented Jun 23, 2020 at 1:07
  • what was your solution? I'm facing the same problem Commented Dec 6, 2023 at 18:56

2 Answers 2

5

The Problem

What you need is something similar to array-contains-all.

So let's say that in firebase you have this:

enter image description here

And then in your code you have something like this:

const usersIDs = [
  'q4nemfzg19OCmwm1EauiZwdYD4z1',
  'UzmgPRtlRSZX44erF6VrkYQ5Kyf1',
];

Then you want to compare with something like this:

yourCollectionRef.where('users', 'array-contains-all', usersIDs).get()
// or 
yourCollectionRef.where('users', '==', usersIDs).get()

But this is currently not possible. The array-contains-all is still a requested feature and the == is not gonna work because the type of the value has to be string, boolean, number, Time, null or docRef and can't be compared to an array.

The Solution

So the good news is that I have a solution for you in case you are willing to change your collection structure.

Instead of saving the data in array, save it in a map object and the items would be the keys.

Like this:

enter image description here

And then you can easily use the filter == as you want. Of course you can transform the array into a map object or simply have it like this:

const usersMap = {
  q4nemfzg19OCmwm1EauiZwdYD4z1: null,
  UzmgPRtlRSZX44erF6VrkYQ5Kyf1: null,
};

And this would be your final query:

yourCollectionRef.where('usersMap', '==', usersMap).get();

Then if you need in the future to get all of the documents from a specific user that's inside the usersMap you can use this query here:

yourCollectionRef.where(`usersMap.${userId}`, '==', null).get();
Sign up to request clarification or add additional context in comments.

4 Comments

Can you please add why '==' is not gonna work? Thanks!
@virus because if you use the '==', the type of the value has to be string, boolean, number, Time, null or docRef. In this case, you cannot compare with an array.
Thanks Frederiko. I'm trying to find a reference in the docs - do you by any chance have a link? I assume when using "==" it will always return false?
Google is not so helpful with the documentation. Here you can check for more info: firebase.google.com/docs/firestore/manage-data/data-types and firebase.google.com/docs/reference/js/firestore_.md#where
2

"array-contains" method has ability to query for elements within arrays. This means you can keep your elements as an array, and easily query for them without having to resort to the map hack.

If you don't want to use this method one alternative could be iterate both arrays until match the values as you need.

However, in this document you can find multiple examples for perform simple and compound queries.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.