[Help Wanted]: My task triggered by onLocation is being killed early
Required Reading
- [x] Confirmed
Plugin Version
4.18.0
Mobile operating-system(s)
- [x] iOS
- [ ] Android
Device Manufacturer(s) and Model(s)
iPhone 15 Pro
Device operating-systems(s)
26.0.2
What do you require assistance about?
My task triggered by onLocation in the background is doing some network calls. These calls are being killed if running to long. Do you have any experiences with how much time the OS grants you to do things in the background?
[Optional] Plugin Code and/or Config
[Optional] Relevant log output
Hey @lfchris,
This is a classic (and very frustrating) problem when dealing with background location on iOS!
To answer your direct question: The time the OS grants you inside the onLocation event is not a full background task window (like 30 seconds or 3 minutes). It's an extremely short window, often just a few seconds, intended only for very lightweight, synchronous processing. This is why your network calls are being killed—iOS is ruthless about this to save battery.
Solution: Don't make network calls in the onLocation handler.
The onLocation event is the wrong place for any asynchronous task that can fail (like a network call). The plugin is designed to handle this for you reliably.
The correct pattern is to use the plugin's built-in HTTP persistence. You configure the plugin with your server URL, and it takes care of everything:
It receives a location.
It immediately saves it to its internal SQLite database (this is very fast and synchronous).
Separately, the plugin uses its own native background task to batch-sync the locations from its database to your server.
This way, the plugin handles all the retries, connection failures, and "task killed" issues for you, and your onLocation event finishes instantly.
Your config should look something like this, (remove any fetch calls from your onLocation):
JavaScript
BackgroundGeolocation.configure({ // YOUR SERVER ENDPOINT url: 'https://your-server.com/api/locations',
// --- Settings for reliability --- autoSync: true, // Automatically sync to the URL autoSyncThreshold: 10, // Sync when 10 locations are queued batchSync: true, // Send locations in a batch (highly recommended) maxBatchSize: 100, // Max 100 locations per POST
// ... your other config (distanceFilter, etc.) }); Your onLocation event should only be used for things like updating the UI if the app is in the foreground.
Hope this helps!
-
when the plug-in in is in the moving state (State.isMoving == true), you have infinite background time -- your http requests should not be frozen.
-
when the plug-in is in the stationary state (ie location-services OFF), the OS will freeze your app almost immediately.
-
see api docs .startBackgroundTask.
-
you will have a better experience if you can offload your http requests to the plug-in's builtin http service.
Hey @lfchris,
This is a classic (and very frustrating) problem when dealing with background location on iOS!
To answer your direct question: The time the OS grants you inside the onLocation event is not a full background task window (like 30 seconds or 3 minutes). It's an extremely short window, often just a few seconds, intended only for very lightweight, synchronous processing. This is why your network calls are being killed—iOS is ruthless about this to save battery.
Solution: Don't make network calls in the onLocation handler.
The onLocation event is the wrong place for any asynchronous task that can fail (like a network call). The plugin is designed to handle this for you reliably.
The correct pattern is to use the plugin's built-in HTTP persistence. You configure the plugin with your server URL, and it takes care of everything:
It receives a location.
It immediately saves it to its internal SQLite database (this is very fast and synchronous).
Separately, the plugin uses its own native background task to batch-sync the locations from its database to your server.
This way, the plugin handles all the retries, connection failures, and "task killed" issues for you, and your onLocation event finishes instantly.
Your config should look something like this, (remove any fetch calls from your onLocation):
JavaScript
BackgroundGeolocation.configure({ // YOUR SERVER ENDPOINT url: 'https://your-server.com/api/locations',
// --- Settings for reliability --- autoSync: true, // Automatically sync to the URL autoSyncThreshold: 10, // Sync when 10 locations are queued batchSync: true, // Send locations in a batch (highly recommended) maxBatchSize: 100, // Max 100 locations per POST
// ... your other config (distanceFilter, etc.) }); Your onLocation event should only be used for things like updating the UI if the app is in the foreground.
Hope this helps!
@justin55afdfdsf5ds45f4ds5f45ds4 Thank you for your comprehensive explanation. I do not think I can use the plugin's built-in HTTP method because I need to do the things via a library which are then doing the network calls. This needs to be done on the device. Concretely, the app subscribes to certain firebase fcm topics on location changes.
- when the plug-in in is in the moving state (State.isMoving == true), you have infinite background time -- your http requests should not be frozen.
- when the plug-in is in the stationary state (ie location-services OFF), the OS will freeze your app almost immediately.
- see api docs .startBackgroundTask.
- you will have a better experience if you can offload your http requests to the plug-in's builtin http service.
@christocracy Thank you for your explanation.
I am using useSignificantChangesOnly, so I do not have the moving and stationary states.
As I already explained to @justin55afdfdsf5ds45f4ds5f45ds4, the app subscribes to certain firebase fcm topics on location changes, so this needs to be done on the device by the fcm library and cannot be offloaded to the plug-in's builtin http service (I think).
But this sounds interesting: startBackgroundTask
Can I just call it from onLocation like:
bg.BackgroundGeolocation.onLocation((bg.Location location) async {
bg.BackgroundGeolocation.startBackgroundTask().then((int taskId) {
subscribeToTopics([topics]).then(() {
BackgroundGeolocation.finish(taskId);
});
});
}, _onLocationError);
This issue is stale because it has been open for 30 days with no activity.
This issue was closed because it has been inactive for 14 days since being marked as stale.