Is there a work-around for the limited firebase query capabilities

101 views Asked by At

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

1

There are 1 answers

0
Doug Stevenson On BEST ANSWER

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.