LocationUpdates/Geofencing not running in background

I only get location updates/geofence updates when the app is running. I’ve put "UIBackgroundModes": ["location", "fetch"]in my app.json (and it shows up in my Info.plist), I’ve defined the task in the global scope, have given my app “always” as well as “background refresh” permissions, but I can’t seem to get it to run in the background.

Relevant code: https://gist.github.com/dereknelson/97c6cb5e6ae36ef3c8668f670b4c3c2d

I know it doesn’t work because there are no requests being made to the server until I opened the app, nor any LocalNotifications generated when I entered and exited two geofences this morning.

I drove 6.5 miles to the gym and back (well over apple’s “significant” location change threshold, on top of the gym being a geofenced region passed to the task), and there was no significant location update nor a geofence update. What am I doing wrong?

@tsapeta / @sjchmiela

I am having a very similar experience.
Were you able to get Location.startLocationUpdatesAsync working in the background?

I am playing around with Geofencing as well and got startLocationUpdatesAsync working in the background, but no luck with startGeofencingAsync.

I’m 99% certain that neither of them worked in the background for me. Do you mind posting your startLocationUpdatesAsync config so I can compare?

to clarify, is this in a standalone app or in the expo client?

I suppose it’s both as I’ve instantiated the same background functions in both the client and my standalone
Forgot I turned off “Always” tracking in the client. It works in the expo client but not the standalone.

i’d double check that your server is working as expected then, i’ve had no issue with using background location in the expo client

Correction, sorry - I forgot I turned off “Always” tracking in the expo client & after turning back on, I am receiving it from the client, but not the standalone. I determine this by prefixing the log with ‘dev/’ if it’s in dev, so it is working in the client but not the standalone.

Here’s what I have for startLocationUpdatesAsync that’s working for me as a standalone in iOS.

  // Define Task in the task manager
  TaskManager.defineTask('GEO_LOCATION_UPDATE', ({ data: { locations }, error }) => {
    if (error) {
      Amplitude.logEventWithProperties("GEO_LOCATION_UPDATE_ERROR", { error, locations });
    Amplitude.logEventWithProperties("GEO_LOCATION_UPDATE", { locations });
  //Register task 
Location.startLocationUpdatesAsync('GEO_LOCATION_UPDATE', {
        accuracy: 4,
        timeInterval: (1000 * 60 * 2),
        distanceInterval: 100,
      }).then(result => console.log('GEO LOCATION UPDATE', result))
1 Like

Hey guys, sorry I didn’t have time to take a look on that, but I’ll try to find some time soon :wink:
So, to sum up, background location works for you on both Expo Client and standalone app, but geofencing works only in Expo Client, right?

No worries! Correct, except I have not gotten geofencing to work in the background in either the client or the standalone

Thanks @tsapeta for taking a look.
Background location (Location.startLocationUpdatesAsync) works for me on both Expo Client and standalone app.
Geofencing (Location.startGeofencingAsync) doesn’t work at all on either.

I just ran another test with both tasks registered and Location Update is working fine, I entered and exited the location specified in my geofencing and didn’t receive a single geofencing event; though location update worked perfectly and reported correct lat/longs all along the way.

It seems like I can build my own geofencing algo using location updates, but it would be nice to use something standard.

1 Like

Here’s another thread that I started earlier with more details on trying to get geofencing working.

To add to the questions above, is it possible to do this on iOS without permanently showing the blue flashing bar at the top of the screen?

Also, does location reporting stop if the user closes the app?

Location does stop reporting (as configured) and switches to background location reporting, which is either after a “significant” location change (500m according to apple’s docs) or if the device enters/exits a geofence

Thank you for giving us the example, I got this error “GEO LOCATION UPDATE undefined” when testing your example.
Could you help me with this?

Hmmm, is your TaskManager.defineTask(‘GEO_LOCATION_UPDATE’) running before Location.startLocationUpdateAsync.

From Expo documentation
TaskManager.defineTask(taskName, task) Defines task function. It must be called in the global scope of your JavaScript bundle. In particular, it cannot be called in any of React lifecycle methods like componentDidMount. This limitation is due to the fact that when the application is launched in the background, we need to spin up your JavaScript app, run your task and then shut down — no views are mounted in this scenario.

Ideally all your TaskManager.defineTasks run outside of components, somewhere in the initial app setup code.
Then you fire off startLocationUpdateAsync in one of your components based on user input or something else.

1 Like

Thanks, I figure out what’s wrong! I am wondering how to test the background location on the simulator when you exit the app?

In your simulator, click on debug > location > Freeway Drive and it’ll simulate you moving around. image

Do you know will this work when you quit the app?