fix: update existing schedule instead of creating new one during rollover

- Find existing enabled notify schedule and update its nextRunAt
- Fallback to finding schedule by kind='notify' && enabled=true if not found by ID
- This ensures getNotificationStatus() finds the updated schedule, not a stale one

Previously, during rollover we were creating a new schedule with a different ID
(daily_rollover_...), but getNotificationStatus() was finding the original schedule
(with ID like notify_... or daily_notification) which still had the old nextRunAt.

The fix:
- First try to find schedule by the provided stableScheduleId
- If not found, find the existing enabled notify schedule (there should only be one)
- Update that schedule's nextRunAt instead of creating a new one
- This ensures getNotificationStatus() returns the correct nextNotificationTime

This matches the pattern used in getNotificationStatus() which finds schedules
with kind='notify' && enabled=true.
This commit is contained in:
Matthew Raymer
2025-12-30 08:28:00 +00:00
parent 9655fa10f8
commit 4c1281754e

View File

@@ -399,10 +399,21 @@ class NotifyReceiver : BroadcastReceiver() {
// Update database schedule with new nextRunAt so getNotificationStatus() returns correct value // Update database schedule with new nextRunAt so getNotificationStatus() returns correct value
// This is critical for rollover scenarios where the UI needs to show the updated time // This is critical for rollover scenarios where the UI needs to show the updated time
// Strategy: Find existing enabled notify schedule and update it (there should only be one)
// This ensures getNotificationStatus() finds the updated schedule, not a stale one
try { try {
runBlocking { runBlocking {
val db = DailyNotificationDatabase.getDatabase(context) val db = DailyNotificationDatabase.getDatabase(context)
val existingSchedule = db.scheduleDao().getById(stableScheduleId)
// First, try to find schedule by the provided stableScheduleId
var scheduleToUpdate = db.scheduleDao().getById(stableScheduleId)
// If not found by ID, find the existing enabled notify schedule (for rollover scenarios)
// getNotificationStatus() finds schedules with kind="notify" && enabled=true
if (scheduleToUpdate == null) {
val allSchedules = db.scheduleDao().getAll()
scheduleToUpdate = allSchedules.firstOrNull { it.kind == "notify" && it.enabled }
}
// Calculate cron expression from trigger time (HH:mm format) // Calculate cron expression from trigger time (HH:mm format)
val calendar = java.util.Calendar.getInstance().apply { val calendar = java.util.Calendar.getInstance().apply {
@@ -413,14 +424,13 @@ class NotifyReceiver : BroadcastReceiver() {
val cronExpression = "${minute} ${hour} * * *" val cronExpression = "${minute} ${hour} * * *"
val clockTime = String.format("%02d:%02d", hour, minute) val clockTime = String.format("%02d:%02d", hour, minute)
if (existingSchedule != null) { if (scheduleToUpdate != null) {
// Update existing schedule with new nextRunAt // Update existing schedule with new nextRunAt
val currentTime = System.currentTimeMillis() // Use the existing schedule's ID (not stableScheduleId) to ensure we update the right one
db.scheduleDao().updateRunTimes(stableScheduleId, existingSchedule.lastRunAt, triggerAtMillis) db.scheduleDao().updateRunTimes(scheduleToUpdate.id, scheduleToUpdate.lastRunAt, triggerAtMillis)
Log.d(SCHEDULE_TAG, "Updated schedule in database: id=$stableScheduleId, nextRunAt=$triggerAtMillis") Log.d(SCHEDULE_TAG, "Updated schedule in database: id=${scheduleToUpdate.id}, nextRunAt=$triggerAtMillis (rollover)")
} else { } else {
// Create new schedule entry for rollover scenarios // No existing schedule found - create new one (shouldn't happen in normal flow)
// This ensures getNotificationStatus() can find the schedule
val newSchedule = Schedule( val newSchedule = Schedule(
id = stableScheduleId, id = stableScheduleId,
kind = "notify", kind = "notify",
@@ -434,7 +444,7 @@ class NotifyReceiver : BroadcastReceiver() {
stateJson = null stateJson = null
) )
db.scheduleDao().upsert(newSchedule) db.scheduleDao().upsert(newSchedule)
Log.d(SCHEDULE_TAG, "Created schedule in database: id=$stableScheduleId, nextRunAt=$triggerAtMillis") Log.d(SCHEDULE_TAG, "Created new schedule in database: id=$stableScheduleId, nextRunAt=$triggerAtMillis")
} }
} }
} catch (e: Exception) { } catch (e: Exception) {