简体   繁体   中英

Firebase Firestore Mulitple Condition Clauses or Cloud Functions, with Flutter

I'm currently using Flutter to develop, and I have an issue I understand that according to the Firebase Documentation: you can only perform a search using just one Array Contains clause .

In my Firestore, I have a Collection which in its documents, it has the field State, City, and Zone, which should all be queried with array contains.

I would let it go, but another programmer mentioned that through CloudFunctions, there is a way to get the Mulitple Array Queries only that it will be slower.

So in a perfect world, I should be able to query with an Array of Zones [Zone1, Zone2, Zone3], with an array of Cities [San Diego, Los Angeles, Washington] and an Array of States [CA, WA, NY] and show results for those.

Any Ideas?

through CloudFunctions, there is a way to get the Mulitple Array Queries only that it will be slower.

Cloud Functions accesses Firestore through the Admin SDK. While it is a separate SDK, most limitations come from the Firestore backend and not its SDK. In this case the Admin SDK too can only have a single array-contains clause per query.

You might want to go back to that customer and ask if they can clarify how they think Cloud Functions could be used here. They probably have something else in mind than this feature suddenly existing there.,

As also @FrankvanPuffelen mentioned in his answer, all the limitations come from the Firestore backend. So all the SDKs share the same constraints, no matter which one you are using.

you can only perform a search using just one Array Contains clause.

That's entirely true.

So in a perfect world, I should be able to query with an Array of Zones [Zone1, Zone2, Zone3], with an array of Cities [San Diego, Los Angeles, Washington] and an Array of States [CA, WA, NY] and show results for those.

Yep, but that's unfortunately currently not possible. Luckily, there's a workaround that can help you achieve the same results, but only if you can change the structure of your document a little bit. So instead of using arrays, you might take into consideration using maps. So your new document structure might look similar to this:

$docId
  |
  --- zones (map)
  |    |
  |    --- zone1: true
  |    |
  |    --- zone2: true
  |    |
  |    --- zone3: true
  |
  --- cities (map)
  |    |
  |    --- San Diego: true
  |    |
  |    --- Los Angeles: true
  |    |
  |    --- Washington: true
  |
  --- states (map)
       |
       --- CA: true
       |
       --- WA: true
       |
       --- NY: true

To get, for example, all documents where "states" contains "CA" and "cities" contains "LA" and "zones" contains "zone1", you can use three consecutive where() calls, as you can see in the following query:

Query query = db.collection("collName")
                .where("states", isEqualTo: "CA")
                .where("cities", isEqualTo: "LA")
                .where("zones", isEqualTo: "zone1");
query.get().then(...);

I would let it go.

Don't do it, since only a simple change in your document structure is required.

Edit:

According to your comment:

would it work if I send it Query that I want just a single zone, a 2 cities, 1 State having a zone out of one of those 2 cities, for example I want data from Zones[Midtown], Cities[Manhattan, Queens], States=[NY] like that having Midtown being a zone of Manhattan and also show all hits for Queens but also hits for Midtown, Manhattan only?

No, it won't. You cannot pass two cities. But it will work if you create two separate queries. The first one would be:

Query firstQuery = db.collection("collName")
                .where("states", isEqualTo: "NY")
                .where("cities", isEqualTo: "Manhattan") //First state
                .where("zones", isEqualTo: "Midtown");

And the second one:

Query secondQuery = db.collection("collName")
                .where("states", isEqualTo: "NY")
                .where("cities", isEqualTo: "Queens") //Second state
                .where("zones", isEqualTo: "Midtown");

Once you get the result of each query, you can then join them on the client. For Android, that would be:

Firestore - Merging two queries locally

In Flutter, that would be something like this:

Flutter merge two firestore streams into a single stream

You might also consider trying this:

How to merge two firestore queries in the Flutter project and How do I remove the duplicate documents from these two streams?

And this:

combine two different collections of firebase in flutter

filter only by "zones" that will make the results you are looking for. I'm guessing here that you want to filter with AND. If so, in you case

Zones [Zone1, Zone2, Zone3] AND Cities [San Diego, Los Angeles, Washington] AND States [CA, WA, NY]

is equal to Zones [Zone1, Zone2, Zone3] since a every document should be like

{ state: 'CA', city: 'San Francisco', zone: 'soma' }

for the case that you only have state and cities in the filter then filter for city, same when only you have states

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM