Timezone-Aware Streak Reminders
This document details the scheduling pipeline, timezone resolution, and multicast delivery of localized evening push notifications (api_internal/lib/streak-reminder.ts) in Scripture Habit.
1. Pipeline Overview
Rather than broadcasting an uniform global notification, an hourly cron job identifies regions experiencing 8:00 PM (20:00) local time, filters users with incomplete daily study, and dispatches localized push notifications.
Pipeline Breakdown
Dynamic Timezone Identification
Evaluates all IANA timezones using Node.js'sIntlAPI to locate regions currently at 20:00 local time (adjusting automatically for Daylight Saving Time).Chunked Firestore Queries
Partitions eligible timezones into 10-item chunks to adhere to Firestoreinquery limits.Localized Completion Filtering
Compares the candidate'slastPostDateagainst their local calendar date string (YYYY-MM-DD), filtering for uncompleted sessions.Multicast Dispatch & Self-Healing Purge
Groups candidate tokens by language preference for batched FCM delivery, automatically purging invalidated tokens on failure feedback.
2. Timezone Resolution & Completion Evaluation
① Detecting 8:00 PM Timezones
Dynamically scans Intl.supportedValuesOf('timeZone') to identify zones whose current local hour is 20.
② Localized Completion Verification
Derives the local YYYY-MM-DD string in the target timezone rather than UTC, comparing it against the user's lastPostDate to prevent erroneous reminder alerts.
3. Query Partitioning & Multicast Delivery
- 10-Item Query Partitioning: Splits target timezones into 10-item arrays to satisfy Firestore operator constraints.
- Multicast Grouping: Bundles tokens by user language, dispatching in batches of up to 500 via
sendEachForMulticast.
4. Automatic Token Purging
Tokens that fail delivery due to app uninstallation or expiration (e.g., messaging/registration-token-not-registered) are parsed from response arrays and deleted from Firestore.