firebase / firebase-ios-sdk

Firebase SDK for Apple App Development
https://firebase.google.com
Apache License 2.0
5.67k stars 1.49k forks source link

Unable to use notIn with inequality filters. #8938

Closed davidhakki closed 3 years ago

davidhakki commented 3 years ago

[REQUIRED] Step 1: Describe your environment

[REQUIRED] Step 2: Describe the problem

Unable to use whereField(notIn) with inequality filters.

Error message: 'Invalid Query. All where filters with an inequality must be on the same field. But you have inequality filters on 'name' and 'dob'

Steps to reproduce:

Setup a query with a notIn and inequality filters.

Relevant Code:

reference = reference.whereField(FieldPath.documentID(), notIn: prohibited)

 if currentUser.minimumAgeFilter != nil {
        reference = reference.whereField("dob", isLessThanOrEqualTo: getDOB(age: currentUser.minimumAgeFilter!))
    }

    if currentUser.maximumAgeFilter != nil {
        reference = reference.whereField("dob", isGreaterThanOrEqualTo: getDOB(age: currentUser.maximumAgeFilter!))
    }

This will result in a crash and the error message above. Frankly I don't think firebase errors should cause an entire app crash but that's a different discussion for a different day.

google-oss-bot commented 3 years ago

I found a few problems with this issue:

mortenbekditlevsen commented 3 years ago

This is the expected and documented behavior:

From the documentation:

Limitations

Note the following limitations for != queries:

Only documents where the given field exists can match the query.
You can't combine not-in and != in a compound query.
In a compound query, range (<, <=, >, >=) and not equals (!=, not-in) comparisons must all filter on the same field.

Firestore queries

Regarding the crashing behavior, many would appreciate and expect the crash since the error is in the domain of 'programmer errors'. Only the programmer can fix the error and crashing makes this easy to spot.

This also means that completely interactive, dynamic and user-created firestore queries I likely not a good idea.

You could argue that the API should be throwing instead, but this would incur a lot of error handling everywhere even though the invalid queries are possible to eliminate by the programmer and avoid entirely.

davidhakki commented 3 years ago

Is there a possible workaround as this is a pretty hefty restriction.

For example a dating app you would want to filter by age and you wouldn't want to see results you already swiped on. I am unable to see a way to make this work and other examples with Firestore.

mortenbekditlevsen commented 3 years ago

The technology behind Firestore appears to be using index scans to perform queries, and this technology generally only supports one 'order' which translates to one inequality comparison. This is already much more powerful than the queries available in the real-time database, but relational databases like SQL databases can perform many other types of queries. It all really depends on your needs. Perhaps your goal could be achieved by organizing data differently, but perhaps it's not as simple - which could mean that Firestore is not the best tool for exactly your problem. Firestore excels in the real-time aspect, the horizontal scalability - and all the hard work that has been put into client synchronization and offline availability - and also the powerful integration with the authentication system. I find the query possibilities really great for many kinds of problems, but there are problems that are perhaps better solved with other technologies. Making our problems fit to specific technologies or technologies fit to our specific problems are some of the exciting challenges of being a developer. 😊

davidhakki commented 3 years ago

Making our problems fit to specific technologies or technologies fit to our specific problems are some of the exciting challenges of being a developer. 😊

Lol not when you are hitting a deadline. Yea I was afraid I may have to consider other databases for what we are trying to accomplish here.