transistorsoft / capacitor-background-fetch

Periodic callbacks in the background for both IOS and Android
78 stars 9 forks source link

Scheduled task not working after app termination #13

Closed Ryner47 closed 1 year ago

Ryner47 commented 1 year ago

Your Environment

Latest Dependencies:
@capacitor/cli: 4.6.2
@capacitor/core: 4.6.2
@capacitor/android: 4.6.2 @capacitor/ios: 4.6.2

Installed Dependencies: @capacitor/ios: not installed @capacitor/core: 4.6.1 @capacitor/cli: 4.6.1 @capacitor/android: 4.6.1

Expected Behavior

The scheduled task should work while the app is terminated

Actual Behavior

A new task is scheduled with a delay of 1000000 milliseconds (16,6 minutes, compatible with minimumFetchInterval of 15 minutes), then the app is closed but after 30 minutes of waiting nothing happens

Steps to Reproduce

  1. Run emulator
  2. Schedule a task with a delay of 1000000 milliseconds (used example code here https://github.com/transistorsoft/capacitor-background-fetch/tree/master/example/src/app/home)
  3. swipe test app or click 'clear all' from homepage to terminate app
  4. wait

Context

In 'performYourWorkHere' function a local notification is performed to see if the scheduled task correctly works; currently the scheduled task is executed correctly only if the app is open or in the background, it seems that the 'enableHeadless' property doesn't work if app is terminated

Debug logs

christocracy commented 1 year ago

Did you implement your Java HeadlessTask?

see api docs Config.enableHeadless

christocracy commented 1 year ago

Here is the /example app’s HeadlessTask:

https://github.com/transistorsoft/capacitor-background-fetch/blob/master/example/android/app/src/main/java/com/transistorsoft/backgroundfetch/capacitor/demo/BackgroundFetchHeadlessTask.java

Ryner47 commented 1 year ago

Did you implement your Java HeadlessTask?

see api docs Config.enableHeadless

Hi, yes I have implemented the Java class HeadlessTask both as indicated here [https://transistorsoft.github.io/capacitor-background-fetch/interfaces/backgroundfetchconfig.html#enableheadless] and as here [https://github.com/transistorsoft/capacitor-background-fetch/blob/master/example/android/app/src/main/java/com/transistorsoft/backgroundfetch/capacitor/demo/BackgroundFetchHeadlessTask.java] but in neither case it works

christocracy commented 1 year ago

Why not provide a smaller interval for easy testing at your work station (Eg 5000ms)? Call scheduleTask, terminate app, observe $ adb logcat.

Ryner47 commented 1 year ago

Why not provide a smaller interval for easy testing at your work station (Eg 5000ms)? Call scheduleTask, terminate app, observe $ adb logcat.

I tried again scheduling a task 'com.transistorsoft.customtask20' with a delay of 20 seconds (20000 ms) so that I could have all time to close the app and analyze the logs. I've attached full log file 'log1_adblogcat.txt' (adb logcat) log1_adblogcat.txt

Here I see that the task has been correctly initialized

01-24 13:59:20.801 17563 17635 D TSBackgroundFetch: {
01-24 13:59:20.801 17563 17635 D TSBackgroundFetch:   "taskId": "com.transistorsoft.customtask20",
01-24 13:59:20.801 17563 17635 D TSBackgroundFetch:   "isFetchTask": false,
01-24 13:59:20.801 17563 17635 D TSBackgroundFetch:   "minimumFetchInterval": 15,
01-24 13:59:20.801 17563 17635 D TSBackgroundFetch:   "stopOnTerminate": true,
01-24 13:59:20.801 17563 17635 D TSBackgroundFetch:   "requiredNetworkType": 0,
01-24 13:59:20.801 17563 17635 D TSBackgroundFetch:   "requiresBatteryNotLow": false,
01-24 13:59:20.801 17563 17635 D TSBackgroundFetch:   "requiresCharging": false,
01-24 13:59:20.801 17563 17635 D TSBackgroundFetch:   "requiresDeviceIdle": false,
01-24 13:59:20.801 17563 17635 D TSBackgroundFetch:   "requiresStorageNotLow": false,
01-24 13:59:20.801 17563 17635 D TSBackgroundFetch:   "startOnBoot": false,
01-24 13:59:20.801 17563 17635 D TSBackgroundFetch:   "forceAlarmManager": false,
01-24 13:59:20.801 17563 17635 D TSBackgroundFetch:   "periodic": false,
01-24 13:59:20.801 17563 17635 D TSBackgroundFetch:   "delay": 20000
01-24 13:59:20.801 17563 17635 D TSBackgroundFetch: }

while here I see that event is received

01-24 13:59:56.068 17719 17719 D TSBackgroundFetch: - Background Fetch event received: com.transistorsoft.customtask20
01-24 13:59:56.090 17719 17719 D TSBackgroundFetch: ☯️  onCreate
01-24 13:59:56.101 17719 17719 D TSBackgroundFetch: - Stopping on terminate
01-24 13:59:56.101 17719 17719 D TSBackgroundFetch: - stop: com.transistorsoft.customtask20
01-24 13:59:56.101 17719 17719 D TSBackgroundFetch: - jobFinished
01-24 13:59:56.103 17719 17719 I TSBackgroundFetch: - cancel taskId=com.transistorsoft.customtask20, jobId=-1755531802
01-24 13:59:56.109   607   714 W JobScheduler: Job didn't exist in JobStore: ee9f680 #u0a159/-1755531802 io.ionic.starter/com.transistorsoft.tsbackgroundfetch.FetchJobService
01-24 13:59:56.109 17719 17719 D TSBackgroundFetch: - onStopJob
01-24 13:59:56.141 17719 17719 D TSBackgroundFetch: ☯️  HeadlessMode? true

but in the app's event list I don't see the task, furthermore the local notification that is in the 'performYourWorkHere' function has not been performed.

I would like to point out that as storage I use '@capacitor/preferences' (https://capacitorjs.com/docs/apis/preferences)

christocracy commented 1 year ago

"stopOnTerminate": true,

headlessTasks require stopOnTerminate: false

Ryner47 commented 1 year ago

stopOnTerminate: false

I tried again scheduling the task 'pippo20' with a delay of 20000 ms with 'stopOnTerminate: false' and the test result remained unchanged:

New complete log file: log2_adblogcat.txt

with

01-24 16:45:01.928 19285 19395 D TSBackgroundFetch: - registerTask: pippo20
01-24 16:45:01.929 19285 19395 D TSBackgroundFetch: {
01-24 16:45:01.929 19285 19395 D TSBackgroundFetch:   "taskId": "pippo20",
01-24 16:45:01.929 19285 19395 D TSBackgroundFetch:   "isFetchTask": false,
01-24 16:45:01.929 19285 19395 D TSBackgroundFetch:   "minimumFetchInterval": 15,
01-24 16:45:01.929 19285 19395 D TSBackgroundFetch:   "stopOnTerminate": false,
01-24 16:45:01.929 19285 19395 D TSBackgroundFetch:   "requiredNetworkType": 0,
01-24 16:45:01.929 19285 19395 D TSBackgroundFetch:   "requiresBatteryNotLow": false,
01-24 16:45:01.929 19285 19395 D TSBackgroundFetch:   "requiresCharging": false,
01-24 16:45:01.929 19285 19395 D TSBackgroundFetch:   "requiresDeviceIdle": false,
01-24 16:45:01.929 19285 19395 D TSBackgroundFetch:   "requiresStorageNotLow": false,
01-24 16:45:01.929 19285 19395 D TSBackgroundFetch:   "startOnBoot": false,
01-24 16:45:01.929 19285 19395 D TSBackgroundFetch:   "jobService": "io.ionic.starter.BackgroundFetchHeadlessTask",
01-24 16:45:01.929 19285 19395 D TSBackgroundFetch:   "forceAlarmManager": false,
01-24 16:45:01.929 19285 19395 D TSBackgroundFetch:   "periodic": false,
01-24 16:45:01.929 19285 19395 D TSBackgroundFetch:   "delay": 20000
01-24 16:45:01.929 19285 19395 D TSBackgroundFetch: }
christocracy commented 1 year ago

From the /example app in this repo:

  1. With app open in foreground, call:

    BackgroundGeolocation.scheduleTask({
    taskId: result.taskId,
    delay: 20000,
    stopOnTerminate: false,
    enableHeadless: true
    });
  2. Terminate app. Observe $ adb logcat *:S TSBackgroundFetch:V

  3. Wait...

01-24 14:33:34.886 29374 29374 D TSBackgroundFetch: - Background Fetch event received: com.transistorsoft.customtask
01-24 14:33:34.889 29374 29374 D TSBackgroundFetch: ☯️  onCreate
01-24 14:33:34.912 29374 29374 D TSBackgroundFetch: 💀 Custom BackgroundFetchHeadlessTask onFetch: com.transistorsoft.customtask
01-24 14:33:34.921 29374 29456 D TSBackgroundFetch: - finish: com.transistorsoft.customtask
01-24 14:33:34.921 29374 29456 D TSBackgroundFetch: - jobFinished
01-24 14:33:34.939 29374 29374 D TSBackgroundFetch: ☯️  HeadlessMode? true

I suggest you remove your logcat filter *:S TSBackgroundFetch and observe unfiltered logs for potential exceptions from your BackgroundFetchHeadlessTask.java implementation.

Ryner47 commented 1 year ago

From the /example app in this repo:

  1. With app open in foreground, call:
BackgroundGeolocation.scheduleTask({
  taskId: result.taskId,
   delay: 20000,
   stopOnTerminate: false,
   enableHeadless: true
});
  1. Terminate app. Observe $ adb logcat *:S TSBackgroundFetch:V
  2. Wait...
01-24 14:33:34.886 29374 29374 D TSBackgroundFetch: - Background Fetch event received: com.transistorsoft.customtask
01-24 14:33:34.889 29374 29374 D TSBackgroundFetch: ☯️  onCreate
01-24 14:33:34.912 29374 29374 D TSBackgroundFetch: 💀 Custom BackgroundFetchHeadlessTask onFetch: com.transistorsoft.customtask
01-24 14:33:34.921 29374 29456 D TSBackgroundFetch: - finish: com.transistorsoft.customtask
01-24 14:33:34.921 29374 29456 D TSBackgroundFetch: - jobFinished
01-24 14:33:34.939 29374 29374 D TSBackgroundFetch: ☯️  HeadlessMode? true

I suggest you remove your logcat filter *:S TSBackgroundFetch and observe unfiltered logs for potential exceptions from your BackgroundFetchHeadlessTask.java implementation.

Hello, 'jobFinished' is present in log 'log2_adblogcat.txt' (log without filters) previously attached, but the actions present in the 'performYourWorkHere' function do not appear to be performed. Does the example in this repo correctly execute what is implemented in 'performYourWorkHere' ('stopOnTerminate: false, enableHeadless: true' case)?

christocracy commented 1 year ago

Does the example in this repo correctly

The /example is a folder within this repo. You can easily browse that code to see for yourself.

Ryner47 commented 1 year ago

Does the example in this repo correctly

The /example is a folder within this repo. You can easily browse that code to see for yourself.

I made some modifications and now a 'Headless' scheduled task works correctly.

Now I would need to clarify a couple of doubts:

Thanks

christocracy commented 1 year ago

in the case of a 'Headless' task executed after app termination, what has been implemented inside the 'performYourWorkHere' function is executed?

there’s nothing special about the method performYourWorkHere(). It’s just an arbitrary method I added to the example to help with code readability.

do I have to implement these functions in the java class?

Yes.

Possibly could you integrate the example java class 'BackgroundFetchHeadlessTask' with these implementations?

I can do it for $300. It will take about 2 hours.

otherwise, Google “Android Java http request” and “Android Java show local notification”.

Ryner47 commented 1 year ago

'Headless'

Hello, could at least the HTTP call be implemented in the 'BackgroundFetchHeadlessTask' class example to make it coherent with the one executed to 'https://www.googleapis.com/books/v1/volumes' in not headless mode and updating demo page status? Finally I would like to ask you for a contact for any paid implementations request. Thanks

christocracy commented 1 year ago

The only reason I do an http request in the JavaScript is to test that the Capacitor webview is able to perform the request; that the request doesn’t get throttled and run only when the app returns to foreground. This is not a problem in pure native code.

I am the only contact at Transistor Software. I am the president and CEO.

https://shop.transistorsoft.com/products/remote-development-consulting-1-hour

Ryner47 commented 1 year ago

The only reason I do an http request in the JavaScript is to test that the Capacitor webview is able to perform the request; that the request doesn’t get throttled and run only when the app returns to foreground. This is not a problem in pure native code.

I am the only contact at Transistor Software. I am the president and CEO.

https://shop.transistorsoft.com/products/remote-development-consulting-1-hour

thanks