RRGT19
RRGT19

Reputation: 1687

Get certain documents from collection in Firestore by a field

I'm doing a web application in Angular 6 and angularfire2. I'm getting all documents in a collection but, now I need to query those documents to get all the documents with the field role.moderator == true.

  private usersCollection: AngularFirestoreCollection<User>;
  users: Observable<UserId[]>;
  moderators: Observable<UserId[]>;

  constructor(
    private afs: AngularFirestore
  ) {
    this.usersCollection = afs.collection<User>(config.collection_users);

    this.users = this.usersCollection.snapshotChanges().pipe(
      map(actions => actions.map(a => {
        const data = a.payload.doc.data() as User;
        const id = a.payload.doc.id;
        return {id, ...data};
      }))
    );

    // Query this.users ?
  }

The interface of a User is:

export interface User {
  firstName: string;
  lastName: string;
  emailAddress: string;
  roles: Roles;
  officeAssignedId: string;
}

export interface UserId extends User {
  id: string;
}

export interface Roles {
  administrator?: boolean;
  moderator?: boolean;
}

To get all users with the role of moderator, I was doing:

getUsersWithModeratorRole() {
    return this.afs.collection<User>(
      config.collection_users,
      ref => ref.where('roles.moderator', '==', true)).snapshotChanges().pipe(
      map(actions => actions.map(a => {
        const data = a.payload.doc.data() as User;
        const id = a.payload.doc.id;
        return {id, ...data};
      }))
    );
  }

The problem is:

  1. I need to subscribe and unsubscribe inside of the component.
  2. I feel that I am duplicating code because I already have the documents (this.users), I just need to query them by a field.
  3. I was doing .take(1) and .toPromise() inside of my getUsersWithModeratorRole method but, only returns me one user and I need all. I thought that with .take(1) will grab all.

My goal is to query the collection that I already have (this.users) to find all users who has the field role.moderator == true or convert the getUsersWithModeratorRole method to a Promise correctly to grab all.

Upvotes: 0

Views: 800

Answers (1)

SnorreDan
SnorreDan

Reputation: 2910

You can create a method that returns an Observable on your service like this:

getUsersWithModeratorRole(): Observable<UserId[]> {
  return this.users.pipe(
    map(users => users.filter(user => user.roles.moderator === true))
  );
}

Or if you want it to return a promise, I think it would be something like this:

getUsersWithModeratorRole(): Promise<UserId[]> {
  return this.users.pipe(
    take(1),
    map(users => users.filter(user => user.roles.moderator === true))
  ).toPromise();
}

Upvotes: 1

Related Questions