local-notifications-scheduler

Implements a Flutter local-notification engine with a pure scheduler, gateway port, and idempotent reconcile.

Updated Aug 22, 2026
One-click install
npx skills add https://github.com/zakariaf/NearlyStop --skill local-notifications-scheduler-zakariaf
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: local-notifications-scheduler
Source: https://github.com/zakariaf/NearlyStop/tree/main/.claude/skills/local-notifications-scheduler
Command: npx skills add https://github.com/zakariaf/NearlyStop --skill local-notifications-scheduler-zakariaf

SYSTEM DOCUMENTATION & REQUIREMENTS

💡 This Skill includes scripts (resource) and references (resource) components.

What problem does it solve? Flutter apps that schedule local reminders often desync from the OS pending-notification set, fire at the wrong hour across DST changes, silently exceed the iOS 64-notification cap, or lose reminders after reboot and backup restore. This Skill enforces a single on-device reminder engine where the local database is the source of truth and the OS pending set is a disposable cache reconciled through one idempotent entrypoint. ## Core Features & Use Cases - Single reconcile entrypoint: All scheduling changes flow through syncNotifications(), which diffs a pure ReminderScheduler.compute output against getPending() and applies targeted cancel/schedule operations. - DST-correct recurrence: Recurring schedules are stored as wall-clock plus recurrence rule and resolved to TZDateTime in tz.local at schedule time, with deterministic IDs that fold in the resolved fire instant so edits reschedule correctly. - Platform compliance and survival: Inexact-alarm default with SCHEDULE_EXACT_ALARM opt-in, iOS ~50-notification budgeting, boot re-arm, isolate-safe tap handlers, and an OEM survival matrix. - Use Case: When editing reminder_scheduler.dart or diagnosing a notification that fired at the wrong hour after a DST change, apply this Skill to keep the math pure, Clock-injected, and verifiable off-device with FakeNotificationGateway. ## Quick Start Ask the AI to review or write the notification scheduling code in notification_gateway.dart or reminder_scheduler.dart following the local-notifications-scheduler rules and run its check scripts before the PR.

Frequently Asked Questions about local-notifications-scheduler

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I schedule local notifications in Flutter without desyncing from the OS?

Route every scheduling change through one syncNotifications() reconcile entrypoint that diffs a pure computed desired set against getPending() and applies targeted cancel/schedule calls. Never call gateway.schedule() or cancel() ad hoc from feature or UI code, since that path cannot be made idempotent.

How do I handle recurring reminders across DST changes in Flutter?

Store recurring schedules as wall-clock hour/minute plus a recurrence rule, never as a UTC instant, and resolve to a TZDateTime in tz.local only at schedule time. Set tz.local from flutter_timezone at startup before any zonedSchedule call, or every notification fires at the wrong local hour.

Why do my iOS local notifications silently stop firing?

iOS silently drops scheduled notifications beyond the 64-notification cap with no error. Budget to about 50 pending notifications, sort future instants ascending, take the nearest window, and refill on every app foreground reconcile.

Should I use USE_EXACT_ALARM or SCHEDULE_EXACT_ALARM on Android?

Use SCHEDULE_EXACT_ALARM as a user-revocable opt-in with canScheduleExactAlarms() checks and silent fallback to inexactAllowWhileIdle. Never declare USE_EXACT_ALARM, because Google Play restricts it to alarm, timer, and calendar apps and risks store rejection.

Why does an edited reminder still fire at the old time?

getPending() exposes only the notification id, not the fire time, so an id derived only from reminderId and occurrenceIndex survives an edit and is skipped by both cancel and schedule loops. Fold the resolved fire instant and content into the deterministic id so an edit produces a new id that gets scheduled while the old one is cancelled.

Can I write to the database from a notification tap handler?

No. The @pragma('vm:entry-point') tap handler runs in a separate isolate with no main-isolate state, and concurrent database access from two isolates risks corruption. Record a lightweight pending-action intent and let the next foreground reconcile do the real work.