FREE SNIPPET

Back to Snippets

Firestore: Next-action queue buckets (Overdue / Today / Tomorrow)

A bounded-query approach for nextActionAt that keeps your queue fast, predictable, and index-friendly.

FirestoreOpsQuery
Receipt: overdue doesn’t hide. it screams.

What this is

The ops queue pattern that prevents “lost leads.”

Queues rot when they’re unbounded. This keeps everything inside time windows, so results stay small and indexes stay sane.

  • Store nextActionAt as a Firestore Timestamp.
  • Query *only* bounded buckets (before today, today range, tomorrow range).
  • Always orderBy nextActionAt and apply a limit.

Code

Language: ts
import {
  collection, getDocs, query, where, orderBy, limit, Timestamp
} from 'firebase/firestore';

type BucketOpts = { before?: Date; start?: Date; end?: Date; lim?: number };

export async function fetchNextActionBucket(
  fs: any,
  colPath: string,
  opts: BucketOpts
) {
  const base = collection(fs, colPath);
  const cs: any[] = [];

  const lim = opts.lim ?? 50;

  if (opts.before) {
    cs.push(where('opsAdmin.nextActionAt', '<', Timestamp.fromDate(opts.before)));
  } else if (opts.start && opts.end) {
    cs.push(where('opsAdmin.nextActionAt', '>=', Timestamp.fromDate(opts.start)));
    cs.push(where('opsAdmin.nextActionAt', '<', Timestamp.fromDate(opts.end)));
  } else {
    return [];
  }

  cs.push(orderBy('opsAdmin.nextActionAt', 'asc'));
  cs.push(limit(lim));

  const snap = await getDocs(query(base, ...cs));
  return snap.docs.map((d: any) => ({ id: d.id, ...(d.data() ?? {}) }));
}