darron1217 / react-native-background-geolocation

Background and foreground geolocation plugin for React Native. Tracks user when app is running in background.
Apache License 2.0
33 stars 38 forks source link

Headless task still running even after executing "BackgroundGeolocation.stop()" #7

Closed raghavdnn closed 3 years ago

raghavdnn commented 3 years ago

I've used BackgroundGeolocation.headlessTask() to get location updates even if the app is killed, which works fine but as soon as I stop the tracking using BackgroundGeolocation.stop() everything stops but as soon as I close the app, the headless task again starts keep on sending locations even without executing BackgrounGeolocation.start() first.

Your Environment

BackgroundGeolocation.on('location', (location) => { // handle your locations here // to perform long running operation on iOS // you need to create background task BackgroundGeolocation.startTask((taskKey) => { // execute long running task // eg. ajax post location // IMPORTANT: task has to be ended by endTask console.log('ON location: ', location); BackgroundGeolocation.endTask(taskKey); }); });

BackgroundGeolocation.headlessTask(async (event) => { if (event.name === 'location' || event.name === 'stationary') { const location = event.params; console.log(location); } });

BackgroundGeolocation.on('error', (error) => { console.log('[ERROR] BackgroundGeolocation error:', error); });

BackgroundGeolocation.on('start', () => { console.log('[INFO] BackgroundGeolocation service has been started'); });

BackgroundGeolocation.on('stop', () => { console.log('[INFO] BackgroundGeolocation service has been stopped'); });

BackgroundGeolocation.checkStatus(({ isRunning }) => { if (isRunning) { BackgroundGeolocation.start(); // service was running -> rebind all listeners } });


* Link to your project: N/A

## Context
<!--- Provide a more detailed introduction to the issue itself, and why you consider it to be a bug -->
The headless task is still executing after closing the app after stopping tracking using `BackgroundGeolocation.stop()`. The foreground notification starts showing in the notification bar, without even executing `BackgroundGeolocation.start()`.

## Expected Behavior
<!--- Tell us what should happen -->
After executing `BackgroundGeolocation.stop()` all tracking related services should stop (which happens perfectly but not if I use headless task)

## Actual Behavior
<!--- Tell us what happens instead -->
All tracking related services stop after executing `BackgroundGeolocation.start()` but as soon as I close the app, the foreground notification pops up and headless code starts executing.

## Possible Fix
<!--- Not obligatory, but suggest a fix or reason for the bug -->

## Steps to Reproduce
<!--- Provide a link to a live example, or an unambiguous set of steps to -->
<!--- reproduce this bug include code to reproduce, if relevant -->
1. Define a headless task
2. Start the service using `BackgroundGeolocation.start()`
3. Stop the service using `BackgroundGeolocation.stop()`
4. Close the app
5. You will see foreground notification as soon as you close/kill the app with headless code executing

## Context
<!--- How has this bug affected you? What were you trying to accomplish? -->
I am trying to successfully stop the tracking of a user whenever he marks his out attendance. After the attendance gets successfully marked, I try to stop the tracking with BackgroundGeolocation.stop() but then the above issue happens.

## Debug logs
<!-- Relevant parts from printAndroidLogs or printIosLogs.
More info in README.md section Debugging.
If you're reporting app crash also provide output of "adb logcat" -->
darron1217 commented 3 years ago

I think the code below is weird.

BackgroundGeolocation.checkStatus(({ isRunning }) => {
  if (isRunning) {
    BackgroundGeolocation.start(); // service was running -> rebind all listeners
  }
});

BackgroundGeolocation.start() doesn't bind anything. You don't have to restart it.

raghavdnn commented 3 years ago

@darron1217 But if I don't do this:

BackgroundGeolocation.checkStatus(({ isRunning }) => {
  if (isRunning) {
    BackgroundGeolocation.start(); // service was running -> rebind all listeners
  }
});

then location doesn't log in the console after closing and reopening the app again. Also If I define a headless task to get locations even if the app is killed, the next time I open the app while service is running, it throws an error: registerHeadlessTask or registerCancellableHeadlessTask called multiple times for same key 'com.marianhello.bgloc.react.headless.Task'

I've tried commenting the headless task, I thought that was preventing locations to show up in console after closing and re-opening the app but the same thing happened. Location does not show up in console after re-opening the app.

darron1217 commented 3 years ago

@raghav-ado I found bug on Android targetSdk 29+ and fixed it. Please update your plugin version to 0.6.6

raghavdnn commented 3 years ago

@darron1217 still same error registerHeadlessTask or registerCancellableHeadlessTask called multiple times for same key 'com.marianhello.bgloc.react.headless.Task after upgrading to version 0.6.6

darron1217 commented 3 years ago

@raghav-ado I guess your code allows calling start() multiple times. You should run start() only if status is not running

walterdl commented 3 years ago

@raghav-ado did you solved it?

raghavdnn commented 3 years ago

@darron1217 Even after starting service only when it's not running, whenever I close the app, wait for headless task to log location and open the app again, I still get registerHeadlessTask or registerCancellableHeadlessTask called multiple times for same key 'com.marianhello.bgloc.react.headless.Task' and location updates stop even when app is open after this error. Maybe service is being stopped after encoutering this error.

darron1217 commented 3 years ago

@raghav-ado Thanks for your feedback. I'll check this issue if available.

walterdl commented 3 years ago

Same problem here

raghavdnn commented 3 years ago

@walterdl I kind of got it to work. I have moved my headless task inside BackgroundGeolocation.on('start', ...) then everything works as expected.

BackgroundGeolocation.on('start', async () => {
  console.log('[INFO] BackgroundGeolocation service has been started');

  // headless task
  BackgroundGeolocation.headlessTask(async (event) => {
    // your task
    }
  });
});

I think that way your headless task only gets registered once and doesn't cause 'multiple times for same key' error. It stops on BackgroundGeolocation.stop() as well.