Firestore - I want to dynamically add where statements to my collection
Asked Answered
B

1

6

Tech: I'm using Angular 7, Firestore, GeoFireX.

Outcome I want: I want to add .where queries if that query is required by the users. For example below I have four .wheres. I might only need two sometimes and therefore will only want to add two using maybe an if statement if user search by sector and brand (see method: basicQueryBuilder)

The code below works, but is not dynamic.

Additionally, can a this.geo.collection from GeoFireX have a .limit(20) just like a normal collection can?

Current Attempt:

  public getFirestoreJobs(queryType: string, limit: number, pageSize: number): Observable<any> {
    limit = limit + pageSize;

    if (queryType === 'geo') {
      const collection = this.geoQueryBuilder();
      const center = this.geo.point(51.5074, 0.1278);
      const radius = 20;

      return collection.within(center, radius, 'point');
    } else {
      const collection = this.basicQueryBuilder();

      return collection.valueChanges();
    }
  }

  public geoQueryBuilder(): any  {
    return this.geo.collection('jobs', ref => ref
      .where('sector', '==', 'teacher')
      .where('brand', '==', 'all')
      .where('payType', '==', 'salary')
      .where('tags', 'array-contains', 'salary'));
  }

  public basicQueryBuilder(): any {
    return this.angularFirestore.collection('jobs', ref => ref
      .where('sector', '==', 'teacher')
      .where('brand', '==', 'all')
      .where('payType', '==', 'salary')
      .where('tags', 'array-contains', 'salary').limit(20));
  }

Second attempt:

  let query = this.angularFirestore.collection('jobs');
  query = query.where('sector', '==', 'teacher');
  query = query.where('brand', '==', 'all');

  return query.valueChanges();

Error I get:

error TS2322: Type 'Query' is not assignable to type 'CollectionReference'.

Billbug answered 12/2, 2019 at 22:0 Comment(9)
Firestore queries use the builder pattern, so you can deal with each stage of the build conditionally by reassigning to some object that represents the current stage of the build.Johnsonian
@DougStevenson the question you labelled this as a duplicate with doesnt work using the query - query.whereBillbug
It should. You'll need to be more specific about what exactly does not work.Johnsonian
@DougStevenson I've added a second attempt above. But I get an error. See above change please. ThanksBillbug
It looks like you need to conditionally apply the filters inside the callback function that accepts ref, not after it. I don't know enough about the angular wrapper for Firestore to try this myself, so I'll remove the dup.Johnsonian
Thank you. I've removed angularfire for this and I just do a normal firestore call. I get this error: error TS2322: Type 'Query' is not assignable to type 'CollectionReference'.Billbug
So slightly biased, but you could use geofirestore which behaves more like regular Firestore (so you can assign your query/collection and dynamically chain and reassign your query). It also supports the limit method, however there are some performance considerations. Also it doesn't return Observables, like the plain Firestore library, but you can use RxJS and create your own Observables.Mollie
Thanks Michael, whats the database fields per document? The document says: g: string; l: GeoPoint; d: DocumentData; But those dont return anythingBillbug
MichaelSolati, do you have pagination for your geofire? I need to use startAfter / StartAt e.g. so I can get 20 new results at a time. Is this possible?Billbug
B
7
import {Query, QueryFn } from '@angular/fire/firestore';

    this.angularFirestore.collection('jobs', ref => {
    let query : Query = ref;
    if(condition1) {
     query = query.where('sector', '==', 'teacher');
    }
    if(condition2) {
     query = query.where('brand', '==', 'all');
    }
    return query;
    })
Boxthorn answered 16/2, 2019 at 18:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.