transistorsoft / react-native-background-fetch

Periodic callbacks in the background for both IOS and Android
MIT License
1.43k stars 191 forks source link

Background task not firing on android #463

Closed noumankhan95 closed 2 weeks ago

noumankhan95 commented 8 months ago
const handleBackgroundFetch = async (taskId) => {
    try {

      console.log("Check bg")

      checkChanges()
    } catch (error) {
      console.error('Error fetching quote:', error);
    }

  };
  const initTask = async () => {
    try {
      const backgroundFetchConfig = {
        minimumFetchInterval: 15, // In minutes
        startOnBoot: true,
        stopOnTerminate: false,
        enableHeadless: true,
      };
// BackgroundFetch.registerHeadlessTask((e))
      const status = await BackgroundFetch.configure(backgroundFetchConfig, async (taskid) => { const res = await handleBackgroundFetch(taskid); BackgroundFetch.finish(taskid); console.log("res ", res) }, (taskId) => { BackgroundFetch.finish(taskId) });
      return status
    } catch (e) {
      console.log("init ", e)
      return e
    }

  }
  useEffect(() => {

    initTask().then(s => console.log("status", s)).catch(e => console.log("u init", e))
    // Clean up the background fetch when the component unmounts

  }, []);

Also i need to know wether the .configure will fire events after every 15 minutes and so and do i need to enable headlessJs for just checking time in background and muting or setting it to normal. i want it the task to keep running even when app is terminated

Your Environment

Expected Behavior

The task should be running in background every 15 minutes even when app is terminated but it doesnt run even once

Actual Behavior

the task is not running in background , it works when i simulate the event , it says job forced but not without simulation

Context

I am trying to change my phone to vibration or normal mode

Debug logs

christocracy commented 8 months ago

When simulated task runs fine, see https://dontkillmyapp.com

noumankhan95 commented 8 months ago

it doesn't run even once and in simulation it says job forced

noumankhan95 commented 8 months ago

does .configure automatically run the job every 15 mins and if so whts the purpose of enabling headlessjs , i didn't understand documentation

christocracy commented 8 months ago

it says job forced

Yes, of course it does. It's normal for simulated tasks.

does .configure automatically run the job every 15 mins

.configure(config) initiates an Android periodic task according to Config.minimumFetchInteval.

and if so whts the purpose of enabling headlessjs , i didn't understand documentation

Because you do not understand the nature of the "Android Application/Activity Life-cycle"; you do not understand how a React Native app renders its UI within the MainActivity and when an Android app is "terminated", it's the MainActivity which is terminated. When an app is launched "Headless", only the Android Application is launched (without a MainActivity), thus your RN application code does not exist in that state.

Only the code in your index.js exists, which is where events from background-fetch are routed in the terminated state. Thus, that is why you must .registerHeadlessTask to receive events in the Android terminated state.

If simulated tasks operate correctly, it is proven that the plugin is setup and configured correctly. The issue is with your device and settings.. see https://dontkillmyapp.com

christocracy commented 8 months ago

Another name for “headless” is “Activity-less”. The Android MainActivity (where your RN App instance lived) is “the head”.

noumankhan95 commented 8 months ago

im surprised even when i schedule a task it doesnt run , is this issue known on android 9 ?

useEffect(() => {

initTask().then(s => console.log("status", s)).catch(e => console.log("u init", e))
// Clean up the background fetch when the component unmounts
BackgroundFetch.scheduleTask({
  taskId: 'com.example.mytask',
  delay: 500, 
  periodic: true, // Set this to true to repeat the task
  stopOnTerminate: false,
  startOnBoot: true,

}).then(s => console.log("s", s)).catch(e => console.log("schedule error", e));

}, []);

christocracy commented 8 months ago

well, you'll never get a task to run with a delay: 500, especially not without forceAlarmManager: true and even then the best you'll get is 1000ms.

christocracy commented 8 months ago

The Android plugin uses JobScheduler by default (which is subject to “Doze Mode”. With forceAlarmManager: true, the plugin uses AlarmManager.

christocracy commented 8 months ago

With forceAlarmManager: true, you CANNOT simulate tasks.

christocracy commented 8 months ago

Without forceAlarmManager: true, the fastest interval you'll ever see is about every 15 minutes.

u15767 commented 6 months ago

I saw, that in case the headless background task fails (e.g., because of an exception as in my case), the scheduled job stays in state waiting. You need to force a timeout first, before you can run it again.

adb.exe shell cmd jobscheduler timeout <your.package.id> 999;
adb.exe shell cmd jobscheduler run -f <your.package.id> 999;
github-actions[bot] commented 4 weeks ago

This issue is stale because it has been open for 30 days with no activity.

github-actions[bot] commented 2 weeks ago

This issue was closed because it has been inactive for 14 days since being marked as stale.