I'm building a dating app that takes many filters. Here is the query:
findMatch(itinerary: IItinerary): void {
const findMatchQuery = this.matchSvc.getMyMatch()
.where('location', '==', itinerary.location)
.where('endDay', '>=', itinerary.startDay)
.where('gender', '==', itinerary.searchGender);
findMatchQuery.get()
.then(listSnapshot => {
this.matches = [];
listSnapshot.forEach(async snapshot => {
let age = moment().diff(snapshot.data().dateOfBirth, 'years');
if ((snapshot.data().startDay <= itinerary.endDay) && (!this.dontShowList.includes(snapshot.id))) {
if ((age <= itinerary.ageRange.upper) && (age >= itinerary.ageRange.lower) && (snapshot.id !== itinerary.id)) {
this.matches.push({
snapshot.data(),
photoUrl: await this.getUserPhoto(snapshot.data().userId)
});
}
}
});
});
}
I realize what I'm doing here isn't good but I don't know another way to do this because you can't use more than one inequality operator.
I have to use ('endDay', '>=', itinerary.startDay), but I also need to filter by age thus I'm using the if statement like so to filter by age:
let age = moment().diff(snapshot.data().dateOfBirth, 'years');
if ((age <= itinerary.ageRange.upper) && (age >= itinerary.ageRange.lower)
this is to make sure I'm only adding users to the list who fall within the desired age range. I'd like to be able to limit my query by 1 and when a user swipes left or right then query firebase again to get another user. I can't limit because I'm using the if statements outside of the query to further filter the list based on the user's desired search.
Say I have a limit of 5 from firebase. But then none of the 5 users fall within the age range. From firebase's perspective I have my 5 users...firebase isn't aware that those 5 were further filtered by the if statement and the user's list is empty. I need my entire query to take all of the filters in effect if I'm able to use the limit() option so I don't have to pull every record from firebase.
And in addition to the age filters I'm actually filtering for a date range...but again, I can only use one inequality operator in the query. So I have an if statement for the following as well: if ((snapshot.data().startDay <= itinerary.endDay)
So what I'm doing here is looking for a date range. This is what I'd like to do:
.where('location', '==', itinerary.location)
.where('endDay', '>=', itinerary.startDay)
.where('gender', '==', itinerary.searchGender)
.where('startDay', '<=', itinerary.endDay)
.where('age', '>=', itinerary.minimumAge)
.where('age', '<=', itinerary.maximumAge);
Obviously I can't use the above query and I'm using the if statements to further filter but I guess there's no way to use the limit() function given those if statements but I thought I'd ask first just in case.
Thanks
Unless you have some way of combining all the range queries into a single field, you can't really bypass Firestore query limitations. What you can do instead is offload some of the filtering on to the client app. So, you can apply a range filter that removes most of the documents, then have the client app remove everything else that's unwanted.
You can possibly speed it up this process by having a backend make the query and further filter the results before sending them back to the client. This would save the time it takes to transfer the unwanted documents.