transistorsoft / react-native-background-fetch

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

How to make headless task to run periodically (every 15 minutes) docs unclear #449

Closed ororsatti closed 8 months ago

ororsatti commented 11 months ago

Your Environment

Expected Behavior

Headless task would trigger every [15 minutes]

Actual Behavior

Not sure. I can only force one event.

Steps to Reproduce

Nothing to reproduce I'm just asking a question that is not clear in the docs.

export const initiateBackgroundFetch = async () => {
  return BackgroundFetch.configure(
    {
      minimumFetchInterval: MIN_FETCH_INTERVAL_IN_MINS,
      stopOnTerminate: false, // Events will run when app terminates.
      startOnBoot: true, // Run events after device reboot.
      enableHeadless: true // use HeadlessJS API
    },
    // eslint-disable-next-line @typescript-eslint/no-misused-promises
    enrichWorkerTask,
    (taskId) => RNBFLogger(RNBFMessageTypes.Timeout, false, taskId)
  );
};

index.js: Screenshot 2023-05-22 at 19 17 16

Workers:


export const headlessEnricherWorker = async (event: HeadlessEvent) => {

  const timeout = event.timeout;
  const taskId = event.taskId;

  if (timeout) {
    RNBFLogger(RNBFMessageTypes.Timeout, true, taskId);
    BackgroundFetch.finish(taskId);
    return;
  }

  RNBFLogger(RNBFMessageTypes.Start, true, taskId);

  const userID = await getPersistentCurrentUserID();
  if (!userID) {
    BackgroundFetch.finish(taskId);
    return;
  }
  try {
    const userData = await getUserDataFromKeychain(userID);
    const encryptedDbSessionKey = await getEncryptedDbSessionKey(userID);
    if (!encryptedDbSessionKey) {
      BackgroundFetch.finish(taskId);
      return;
    }
    const decryptedDbSessionKey = decryptDbSessionKey(
      encryptedDbSessionKey,
      userData.publicKey.key,
      userData.privateUserData.privateKey
    );
    await scheduleEnrich(decryptedDbSessionKey, userData.privateUserData.privateKey, [], BACKGROUND_ENRICH_COUNT);
  } catch (error) {
    BackgroundFetch.finish(taskId);
    return;
  }
  BackgroundFetch.finish(taskId);
};

const enrichWorkerTask = async (taskId: string) => {
  try {

    const userData = requireCurrentUserData();
    const dbSessionKey = requireDBSessionKey();
    await scheduleEnrich(dbSessionKey, userData.privateUserData.privateKey, [], BACKGROUND_ENRICH_COUNT);

    BackgroundFetch.finish(taskId);
  } catch (error) {
    BackgroundFetch.finish(taskId);
  }
};

Context

Run a headless task every 15 minutes. From the docs it can be inferred that a headless task will run every 15 minutes ( or how many is the interval)

Debug logs

Just a question no logs here

ororsatti commented 11 months ago

@christocracy

christocracy commented 11 months ago

You didn’t post any code. How can I answer if you don’t show how you’re configuring / using the plug-in??

ororsatti commented 11 months ago

You didn’t post any code. How can I answer if you don’t show how you’re configuring / using the plug-in??

Add relevant code to the question. Sorry

ororsatti commented 11 months ago

Also @christocracy simulated events works. tested on the simulator.

If I wait the 15 minutes I dont see any events firing

christocracy commented 11 months ago

If simulated events work, that’s all you need to know.

everything else is up to the OS. Test on a real device and see https://dontkillmyapp.com

ororsatti commented 11 months ago

If simulated events work, that’s all you need to know.

everything else is up to the OS. Test on a real device and see https://dontkillmyapp.com

Thanks. but headless events should run periodically too if everything goes smoothly? Just making sure because that wasnt clear on the docs

AmirBraham commented 8 months ago

Any news regarding this issue ?

ororsatti commented 8 months ago

Any news regarding this issue ?

Any thing you need to know?

AmirBraham commented 8 months ago

I tried configuring a task with these params { forceAlarmManager: false, periodic: true, enableHeadless:true, stopOnTerminate: false, startOnBoot: true,} I can fire the event with the adb command just fine when the app is open or running in the background , however , if I close the app and try to fire the task using adb , I would get No task registered for key BackgroundFetch even though I'm sure stopOnTerminate is set to false in android ! Any help is much appreciated

christocracy commented 8 months ago

See api docs BackgroundFetchConfig.enableHeadless

AmirBraham commented 8 months ago

I'm trying to create periodic task that runs every X minutes even if the app is closed or the user reboots the device ( X > 15mins). From my understanding of the docs , when I add a headless task , it would run once the app is terminated but I can't seem to schedule it to run every X minutes. I can't also use a setInterval inside the headless task because it will cause Timeout. Thanks !

christocracy commented 8 months ago

See API docs enableHeadless to learn how to .registerHeadlessTask(yourHeadlessFunction);

BackgroundFetch.configure({
  minimumFetchInterval: 15,
  enabledHeadless: true,
  stopOnTerminate: false,
  startOnBoot: true
}, async (taskId) => {
  console.log('[BackgroundFetch] taskId', taskId);
  // perform work here.
  BackgroundFetch.finish(taskId);
}, async (taskId) => {
  console.log('[BackgroundFech] TIMEOUT: ', taskId);
  BackgroundFetch.finish(taskId);
});
AmirBraham commented 8 months ago

I have followed the example to add a headlessTask to index.js but how do I make sure that the headlessTask is periodic ? Because from the docs , periodic is only valid only for BackgroundFetch.scheduleTask . Thanks for your help

christocracy commented 8 months ago

BackgroundFetch.configure(youConfig) AUTOMATICALLY initiates a periodic task.

You do NOT need to execute .scheduleTask.

AmirBraham commented 8 months ago

Okay perfect ! Thanks for your help