diff --git a/doc/plugin-fix-scheduleExactNotification-calls.md b/doc/plugin-fix-scheduleExactNotification-calls.md new file mode 100644 index 00000000..dba699ce --- /dev/null +++ b/doc/plugin-fix-scheduleExactNotification-calls.md @@ -0,0 +1,108 @@ +# Plugin fix: Update Java call sites for scheduleExactNotification (8th parameter) + +## Problem + +After adding the 8th parameter `skipPendingIntentIdempotence: Boolean = false` to `NotifyReceiver.scheduleExactNotification()` in NotifyReceiver.kt, the Java callers still pass only 7 arguments. That causes a compilation error when building an app that depends on the plugin: + +``` +error: method scheduleExactNotification in class NotifyReceiver cannot be applied to given types; + required: Context,long,UserNotificationConfig,boolean,String,String,ScheduleSource,boolean + found: Context,long,UserNotificationConfig,boolean,,String,ScheduleSource + reason: actual and formal argument lists differ in length +``` + +**Affected files (in the plugin repo):** +- `android/src/main/java/com/timesafari/dailynotification/DailyNotificationReceiver.java` +- `android/src/main/java/com/timesafari/dailynotification/DailyNotificationWorker.java` + +## Current Kotlin signature (NotifyReceiver.kt) + +```kotlin +fun scheduleExactNotification( + context: Context, + triggerAtMillis: Long, + config: UserNotificationConfig, + isStaticReminder: Boolean = false, + reminderId: String? = null, + scheduleId: String? = null, + source: ScheduleSource = ScheduleSource.MANUAL_RESCHEDULE, + skipPendingIntentIdempotence: Boolean = false // 8th parameter +) +``` + +## Required change + +In both Java files, add the **8th argument** to every call to `NotifyReceiver.scheduleExactNotification(...)`. + +### 1. DailyNotificationReceiver.java + +**Location:** around line 441, inside `scheduleNextNotification()`. + +**Current call:** +```java +com.timesafari.dailynotification.NotifyReceiver.scheduleExactNotification( + context, + nextScheduledTime, + config, + false, // isStaticReminder + null, // reminderId + scheduleId, + com.timesafari.dailynotification.ScheduleSource.ROLLOVER_ON_FIRE +); +``` + +**Fixed call (add 8th argument):** +```java +com.timesafari.dailynotification.NotifyReceiver.scheduleExactNotification( + context, + nextScheduledTime, + config, + false, // isStaticReminder + null, // reminderId + scheduleId, + com.timesafari.dailynotification.ScheduleSource.ROLLOVER_ON_FIRE, + false // skipPendingIntentIdempotence – rollover path does not skip +); +``` + +### 2. DailyNotificationWorker.java + +**Location:** around line 584, inside `scheduleNextNotification()`. + +**Current call:** +```java +com.timesafari.dailynotification.NotifyReceiver.scheduleExactNotification( + getApplicationContext(), + nextScheduledTime, + config, + false, // isStaticReminder + null, // reminderId + scheduleId, + com.timesafari.dailynotification.ScheduleSource.ROLLOVER_ON_FIRE +); +``` + +**Fixed call (add 8th argument):** +```java +com.timesafari.dailynotification.NotifyReceiver.scheduleExactNotification( + getApplicationContext(), + nextScheduledTime, + config, + false, // isStaticReminder + null, // reminderId + scheduleId, + com.timesafari.dailynotification.ScheduleSource.ROLLOVER_ON_FIRE, + false // skipPendingIntentIdempotence – rollover path does not skip +); +``` + +## Other call sites + +Kotlin call sites (NotifyReceiver.kt, DailyNotificationPlugin.kt, ReactivationManager.kt, BootReceiver.kt) use **named parameters**, so they already get the default for `skipPendingIntentIdempotence` and do not need changes. Only the **Java** call sites use positional arguments, so only the two files above need the 8th argument added. If you add new Java call sites later, pass the 8th parameter explicitly: `false` for rollover/fire paths, `true` only where the caller has just cancelled this schedule and you intend to skip the PendingIntent idempotence check. + +## Verification + +After updating the plugin: + +1. Build the plugin (e.g. `./gradlew :timesafari-daily-notification-plugin:compileDebugJavaWithJavac` or full Android build from a consuming app). +2. Ensure there are no “actual and formal argument lists differ in length” errors. diff --git a/package-lock.json b/package-lock.json index 285756a7..9632beb5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9452,8 +9452,8 @@ } }, "node_modules/@timesafari/daily-notification-plugin": { - "version": "1.1.0", - "resolved": "git+https://gitea.anomalistdesign.com/trent_larson/daily-notification-plugin.git#bf90f158ac9d6c4a4cd6b1a5d5849abab4455495", + "version": "1.1.3", + "resolved": "git+https://gitea.anomalistdesign.com/trent_larson/daily-notification-plugin.git#a62f54b8a877d78f757373897b36804c203b8351", "license": "MIT", "workspaces": [ "packages/*" diff --git a/src/services/notifications/NativeNotificationService.ts b/src/services/notifications/NativeNotificationService.ts index df8042a3..06f0363b 100644 --- a/src/services/notifications/NativeNotificationService.ts +++ b/src/services/notifications/NativeNotificationService.ts @@ -44,15 +44,10 @@ export class NativeNotificationService implements NotificationServiceInterface { private readonly platformName = "native"; /** - * Reminder/schedule ID used for cancel and getStatus lookup. - * - iOS: We pass this when scheduling so the plugin stores and returns it; use a stable id. - * - Android: We do not pass id (plugin uses "daily_notification") to avoid second-schedule bug. + * Stable schedule/reminder ID used for schedule, cancel, and getStatus. + * Same value on iOS and Android (plugin v1.1.2+ fixes Android reschedule with custom id). */ - private get reminderId(): string { - return Capacitor.getPlatform() === "ios" - ? "daily_timesafari_reminder" - : "daily_notification"; - } + private readonly reminderId = "daily_timesafari_reminder"; /** * Native notifications are always supported on iOS/Android @@ -339,25 +334,21 @@ export class NativeNotificationService implements NotificationServiceInterface { }); } - // iOS: pass id so plugin stores/returns it (getStatus and verification find it). - // Android: omit id so plugin uses "daily_notification" (avoids second-schedule bug). const scheduleOptions: { time: string; title: string; body: string; sound: boolean; priority: "low" | "default" | "high"; - id?: string; + id: string; } = { time: options.time, title: options.title, body: options.body, sound: true, priority: (options.priority || "normal") as "low" | "default" | "high", + id: this.reminderId, }; - if (Capacitor.getPlatform() === "ios") { - scheduleOptions.id = this.reminderId; - } logger.debug( "[NativeNotificationService] Calling scheduleDailyNotification with options:", scheduleOptions,