Search code examples
typescriptfirebasegoogle-cloud-firestorequerying

Is there an easier way to query Cloud Firestore to get all the documents in a specific collection that a user has NOT seen?


I'm developing a mobile application in Angular. The home screen of the app is a contests page where the user chooses which of the two items they like better.

On initialization, this page gets calls backend code that retrieves the contest data from Cloud Firestore.

I have a solution that works already, which is: looping over all the contests that were created after a given date. But I'm concerned about efficiency here. I want 2 things...

  1. Minimize the data that the user is downloading (reduce lag)
  2. Minimize the number of queries and document reads (reduce cost)

Example of TypeScript that returns exactly what I'm looking for:

import * as firebase from 'firebase/app';

contestsRef = firebase.firestore().collection('Contests');

async getAllContestsForUser() {
    const rightNow = new Date(Date.now());
    const contests = new Array<Contest>();
    await this.contestsRef
      .where('closeDateTime', '>', rightNow.toISOString())
      .get()
      .then(querySnapshot => {
        querySnapshot.forEach(contest => {
          this.contestsRef
            .doc(contest.id)
            .collection('Voters')
            .doc(this.userId)
            .get()
            .then(voter => {
              if (!voter.exists) {
                // this user did not vote on contest
                contests.push({ ...contest.data(), id: contest.id });
              }
            });
        });
      });
    return contests;
  }

The results of this code is exactly what I want: an array of Contests that the user has not seen before, but I wonder if there is a better, more efficient way to do it using Firestore queries?


Solution

    1. Minimize the data that the user is downloading (reduce lag)

    If you want to minimize the data that you are getting, you should consider reducing the number of documents that you get in a single query, since in Firestore the query performance depends on the number of items you request and not of the number of items your request them from.

    1. Minimize the number of queries and document reads (reduce cost)

    The simplest solution would be to use a limit() call. This will limit the mumber of documents that you get from a query. This is a common practice since getting all the data at once isn't a good practice. So I recommend you loading your data in smaller chunks.