I had a little paywall related issue crop up in SquadWOD the other day, I want to limit the number of challenges a user can make per month to encourage them to upgrade to the paid membership. This is the perfect example of a freemium limit as the more challenges a user makes the more reads and writes they create in the system and in FireBase that literally costs more money.
The query I wanted to make was "how many challenges has this user made in the past month?" Simple enough in SQL, something like:
SELECT
*
FROM
challenges
WHERE
user_id == USERID
AND created_at > StartOfCurrentMonth;
Having the multiple where clauses SQL makes this quick, simple and fast. However, with AngularFire there is no support for multiple where clauses when querying a FireStore collection like this and so I was left with a few choices:
None of the above felt great as I really want to minimise how often I need to read from the database so I decided to take advantage of the fact that this is a very predicable search clause "this month, this user, how many records?" and add a multi-column index made up of the creation month and userID.
// add class property
creationFilterIndex: string;
// set index when creating challenge
creationFilterIndex: `${createdAt.format('YYYYMM')}${this.user.id}`
// eg: 202006udfjhsflienamamdnjfhg
// search on this property in FireBase
getTotalChallengesMadeThisMonth(user: User): Observable {
return this.db.collection(
'challenges',
ref => ref.where('creationFilterIndex',
'==',
`${moment().format('YYYYMM')}${user.id}`)
).valueChanges().pipe(map(actions => {
return actions.length;
}));
}