Raja0sama / rn-foreground-service

Foreground Service for React Native made with ❤
https://rn-foreground.vercel.app/
148 stars 70 forks source link

Unable to handle hooks in background mode #63

Closed matheusyuri7 closed 1 year ago

matheusyuri7 commented 1 year ago

Hello,

I'm developing a fitness app and I need to update some hooks in background (time, speed, location, calories, etc), but it doesn't update when I'm running on background. How can I set hooks and run useEffects in background?

const [seconds, setSeconds] = useState(0);

function onNewStart() {
      ReactNativeForegroundService.add_task(
        () => handleBackgroundActions(),
        {
          delay: 1000,
          onLoop: true,
          taskId: 111,
          onError: (e) => console.log(`Error logging:`, e),
        },
      );

      ReactNativeForegroundService.start({
        id: 111,
        title: 'Fitness Challenge',
        message: (distance / 1000).toFixed(2).toString() + ' km / ' + calories.toFixed(0).toString() + ' kcal - ' + seconds,
        importance: '2',
        icon: 'ic_notifications',
        largeIcon: 'ic_notifications',
        color: '#9A1E15',
        button: true,
        buttonText: "Pause",
      });
    }

function handleBackgroundActions() {

      Geolocation.getCurrentPosition(
        (position) => {
          handleDuration();
          handleTrackUpdate(position);
        },
        (error) => {
          // See error code charts below. 
          console.log(error.code, error.message);
        },
        { enableHighAccuracy: true, timeout: 15000, maximumAge: 10000 }
      );
    }

async function handleDuration() {
      rest.handleTimeToShow(seconds);

      setTimeout(() => {
        setSeconds(seconds + 1);
      }, 844);
      console.log(seconds);
    }
Raja0sama commented 1 year ago

You need to understand in the headless task, also known as the Background task, you don't have a react instance, rather just javascript execution; therefore whatever state you try to update would be useless. What you might be able to use is localstorage of the application, Why? ask yourself is that what you need?

Let's say you have a task, And whenever it gets a position, you need to update the notification, like a timer.

You would need to directly update the notification itself by using .update method and update the notification with the new data.

here is an example that shows a progress bar on the notification and see how I am maintaining a state

{
    ReactNativeForegroundService.add_task(() => update(), {
      delay: 1000,
      onLoop: true,
      taskId: 'taskid',
      onError: e => console.log(`Error logging:`, e),
    });
    let counter = 0;

    const update = () => {
      if (counter >= 100) {
        ReactNativeForegroundService.stop();
      }
      counter += 2;
      ReactNativeForegroundService.update({
        id: 1244,
        title: 'Foreground Service',
        message: 'you are online!',
        importance: 'min',
        icon: 'ic_launcher_foreground',
        button: true,
        buttonText: 'WOah',
        visibility: 'secret',
        setOnlyAlertOnce: true,
        buttonOnPress: 'cray',
        progress: {
          max: 100,
          curr: counter,
        },
      });
    };
  }
matheusyuri7 commented 1 year ago

Thanks again for the explanation @Raja0sama ! I was able to do what I need by using Async Storage.