From fa8028a6986c88178e7cdb7a6351e3421a0b86d6 Mon Sep 17 00:00:00 2001 From: Jose Olarte III Date: Wed, 18 Feb 2026 18:29:11 +0800 Subject: [PATCH] fix(android): prevent duplicate reminder notification on first-time setup Do not enqueue DailyNotificationFetchWorker for static reminder schedules. Display is already handled by the single NotifyReceiver alarm; prefetch was using fallback content and scheduling a second alarm via legacy DailyNotificationScheduler, causing two notifications at fire time. --- .../DailyNotificationPlugin.kt | 46 ++----------------- 1 file changed, 5 insertions(+), 41 deletions(-) diff --git a/android/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.kt b/android/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.kt index 604c7c0..24e963e 100644 --- a/android/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.kt +++ b/android/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.kt @@ -2683,47 +2683,11 @@ object ScheduleHelper { skipPendingIntentIdempotence = true ) - // Always schedule prefetch 2 minutes before notification - // (URL is optional - native fetcher will be used if registered) - val fetchTime = nextRunTime - (2 * 60 * 1000L) // 2 minutes before - val delayMs = fetchTime - System.currentTimeMillis() - - if (delayMs > 0) { - // Schedule delayed prefetch - val inputData = Data.Builder() - .putLong("scheduled_time", nextRunTime) - .putLong("fetch_time", fetchTime) - .putInt("retry_count", 0) - .putBoolean("immediate", false) - .build() - - val workRequest = OneTimeWorkRequestBuilder() - .setInitialDelay(delayMs, TimeUnit.MILLISECONDS) - .setInputData(inputData) - .addTag("prefetch") - .build() - - WorkManager.getInstance(context).enqueue(workRequest) - - Log.i("ScheduleHelper", "Prefetch scheduled: fetchTime=$fetchTime, notificationTime=$nextRunTime, delayMs=$delayMs") - } else { - // Fetch time is in the past, schedule immediate fetch - val inputData = Data.Builder() - .putLong("scheduled_time", nextRunTime) - .putLong("fetch_time", System.currentTimeMillis()) - .putInt("retry_count", 0) - .putBoolean("immediate", true) - .build() - - val workRequest = OneTimeWorkRequestBuilder() - .setInputData(inputData) - .addTag("prefetch") - .build() - - WorkManager.getInstance(context).enqueue(workRequest) - - Log.i("ScheduleHelper", "Immediate prefetch scheduled: notificationTime=$nextRunTime") - } + // Do not enqueue prefetch for static reminders: display is already in the NotifyReceiver + // alarm. Prefetch is for "fetch content then show"; for static reminders there is nothing + // to fetch. Enqueueing prefetch would cause the worker to use fallback content and + // schedule a second alarm via legacy DailyNotificationScheduler, resulting in duplicate + // notifications at fire time. // Store schedule in database val schedule = Schedule(