transistorsoft / react-native-background-fetch

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

Scheduled background task is performing only when the app is launched from background to foreground in iOS #474

Closed AppalaNaidu01 closed 2 weeks ago

AppalaNaidu01 commented 6 months ago

Your Environment

Expected Behavior

A scheduled trigger should happen when the app is in the background, in that trigger it should fetch some data from the server and display local notifications.

Actual Behavior

The scheduled task happens when the user launches the app from the background to the foreground, as I can see that the notifications are showing up every time only when I open the app. Also, when I simulated using the lldb command by closing the app, I could see that the API call and all the consecutive methods were calling only when I opened the app.

Steps to Reproduce

Context

I need to do all these steps when a scheduled background fetch task triggers:

const useBackgroundFetchNotificationWorker = () => {
  const {insertMultipleNotifications} = useRealmNotificationManager();
  const [fetchProgressStatus, setFetchProgressStatus] = useState(
    fetchProgressState.cool,
  );

  const performTask = useCallback(async () => {
    try {
      setFetchProgressStatus(fetchProgressState.inprogress);
      const newNotifications = await fetchNewNotificationsFromServer();
      if (newNotifications && newNotifications.length > 0) {
        await notifyUser(newNotifications);
        await storeReceivedNotificationIDsToAsyncStorage(newNotifications);
        // store data to realm here
        insertMultipleNotifications(
          prepareNotificationsPayloadToStoreToRealm(newNotifications),
        );
      }
    } catch (error) {
      setFetchProgressStatus(fetchProgressState.cool);
      console.error('Error in performTask:', error);
    } finally {
      setFetchProgressStatus(fetchProgressState.cool);
    }
  }, []);

  // onEvent is called periodically when RNBF triggers an event
  const onEvent = useCallback(
    async taskId => {
      try {
        await performTask();
        BackgroundFetch.finish(taskId);
      } catch (error) {
        BackgroundFetch.finish(taskId);
      }
    },
    [performTask],
  );

  // The timeout function is called when the OS signals that the task has reached its maximum execution time.
  const onTimeOut = async taskId => {
    try {
      // Clean-up work if needed
      BackgroundFetch.finish(taskId);
    } catch (error) {
      console.error('Error in onTimeOut:', error);
      BackgroundFetch.finish(taskId);
    }
  };

const initiateBackgroundWorker = useCallback(async () => {
    const status = await BackgroundFetch.configure(
      {
        minimumFetchInterval: BACKGROUND_FETCH_INTERVAL,
      },
      onEvent,
      onTimeOut,
    );
    // BackgroundFetch.start(); // Not needed
  }, [onEvent]);

  useEffect(() => {
    const initiateWorker = async () => {
      // Initiate background worker
      await initiateBackgroundWorker();
    };
    initiateWorker();
  }, []);

  return {};
};

Debug logs

christocracy commented 6 months ago

I think you're just not waiting long enough in the background. Events are not triggered after exactly 15 min, and often not anything even close to that.

It can take days before Apple's machine-learning algorithm figures out how often to fire events (based upon how often and how long your app is used). I suggest you leave your app in the background for several days and evaluate progress then. You will see that eventually events start firing in the background.

christocracy commented 6 months ago

There is an /example app in this repo which persists fetch events and renders them to a List component. Install the /example app on your device and let it run untouched for a long period of time in the background.

christocracy commented 6 months ago

Actually, you should bring your app to the foreground at least once daily. If you don't, Apple will assume your app is unused and stop firing events.

aperez-sw commented 4 months ago

One question, If the app has not been opened after updating with the new code, is there any chance for the task to run ?

christocracy commented 4 months ago

I don't know.

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.