HttpConfig class
HTTP / Networking Configuration
The HttpConfig group controls how recorded locations are uploaded to your server. It defines the endpoint, HTTP verb, headers and params, batching behavior, and request timeouts. These options apply to all automatic syncs as well as manual syncs triggered by the app.
BackgroundGeolocation.ready(Config(
http: HttpConfig(
url: 'https://example.com/locations',
autoSync: true,
params: {
"user_id": 1234
}
}
));
Overview
The SDK persistently stores each recorded location in its internal SQLite
database before attempting to upload it. The HTTP Service continuously
consumes this queue of stored records in the background. For each record,
the service acquires a record-level lock to prevent concurrent or
duplicate uploads, serializes the record into an HTTP request, and posts it
to the configured url. If the server responds with any 2xx status code,
the record is considered successfully delivered and is deleted from the
SQLite database. Failed or timed-out uploads remain locked until released,
after which they are retried later when network conditions improve.
The uploader operates automatically and reliably across background execution, app termination, and device reboot. When connectivity returns, it resumes processing any remaining records in the queue to maintain delivery integrity.
| Area | Keys | Notes |
|---|---|---|
| Destination | url, method |
method defaults to POST. |
| Payload shape | rootProperty, params, headers |
Controls JSON body and headers. |
| Sync cadence | autoSync, autoSyncThreshold, batchSync, maxBatchSize |
Immediate vs batched uploads. |
| Network policy | disableAutoSyncOnCellular, timeout |
Conserve data / battery. |
How uploads work
- Each recorded location is persisted to SQLite.
- The HTTP Service locks pending records to prevent duplicate uploads.
- Locked records are serialized and sent to the configured
url. - On a successful 2xx response, uploaded records are deleted.
- Failed or timed-out records are unlocked and retried later.
The SQLite buffer
The database is a durable, rolling buffer. It prefers to be empty. Records are removed when:
- Your server returns a 2xx (see HttpEvent).
- You call BackgroundGeolocation.destroyLocations.
- PersistenceConfig.maxDaysToPersist expires (rolling TTL).
- PersistenceConfig.maxRecordsToPersist would be exceeded (oldest dropped).
Inspect the queue with BackgroundGeolocation.count and fetch with BackgroundGeolocation.locations.
Payload composition
-
Body: Location uploads are JSON. If
batchSyncistrue, an array of records is sent. IfrootPropertyis set, the payload becomes{ "<rootProperty>": [...] }. -
Headers: Merged from HttpConfig.headers (and authorization when configured). For authorization refresh requests, see the Authorization docs; those use their own
Content-Type. -
Params: Key/value pairs merged into each outgoing payload (at the root or under
rootProperty).
The SDK applies an appropriate JSON content type for location uploads; authorization
refresh requests use application/x-www-form-urlencoded.
Sync strategy
autoSync: Upload immediately after each record.autoSyncThreshold: Wait until N records before auto-syncing.batchSync: Combine multiple records into one request.maxBatchSize: Limit records per request.timeout: Max request duration (ms).disableAutoSyncOnCellular: Queue until Wi-Fi is available.
Note: If autoSyncThreshold is set, it is ignored during
BackgroundGeolocation.onMotionChange transitions so that state changes are not delayed.
Error handling & retries
On non-2xx responses or connection failures, records remain in the local queue. The uploader retries automatically when conditions improve. Triggers include:
- A new location recorded
- App lifecycle changes (pause/resume, boot)
- BackgroundGeolocation.onConnectivityChange events
- BackgroundGeolocation.onHeartbeat ticks
- iOS background fetch
You can also call BackgroundGeolocation.sync manually at any time.
HTTP Logging
You can observe the SDK performing HTTP in the logs (see the Debugging guide). Example:
╔═════════════════════════════════════════════
║ LocationService: location
╠═════════════════════════════════════════════
╟─ 📍 Location[45.519199,-73.617054]
✅ INSERT: 70727f8b-df7d-48d0-acbd-15f10cacdf33
╔═════════════════════════════════════════════
║ HTTP Service
╠═════════════════════════════════════════════
✅ Locked 1 records
🔵 HTTP POST: 70727f8b-df7d-48d0-acbd-15f10cacdf33
🔵 Response: 200
✅ DESTROY: 70727f8b-df7d-48d0-acbd-15f10cacdf33
| # | Log entry | Description |
|---|---|---|
| 1 | 📍Location |
Location received from native Location API. |
| 2 | ✅INSERT |
Record inserted into the SDK’s SQLite database. |
| 3 | ✅Locked |
HTTP service locks record(s) to prevent duplicate uploads. |
| 4 | 🔵HTTP POST/PUT/… |
Attempt to upload to your configured url. |
| 5 | 🔵Response |
Response status from your server. |
| 6 | ✅DESTROY or UNLOCK |
On 2xx, record is deleted; otherwise it’s unlocked for a future retry. |
Remote control via HTTP response (RPC)
Your server can remotely invoke SDK commands by returning a JSON body containing
a background_geolocation payload. The SDK scans the JSON and executes commands
synchronously upon receipt of the HTTP response.
Shape (multiple commands):
{
"background_geolocation": [
["command1", <optional argument>],
["command2"]
]
}
Shape (single command):
{
"background_geolocation": ["stop"]
}
Supported commands
| Command | Arguments | Description |
|---|---|---|
start |
none | BackgroundGeolocation.start() |
stop |
none | BackgroundGeolocation.stop() |
startGeofences |
none | BackgroundGeolocation.startGeofences() |
changePace |
Boolean |
BackgroundGeolocation.changePace(true/false) |
setConfig |
{Config} (compound-form recommended) |
BackgroundGeolocation.setConfig({...}) |
addGeofence |
{Geofence} |
BackgroundGeolocation.addGeofence({...}) |
addGeofences |
[{Geofence}, ...] |
BackgroundGeolocation.addGeofences([...]) |
removeGeofence |
identifier:String |
BackgroundGeolocation.removeGeofence(id) |
removeGeofences |
none or [identifier:String,...] |
Remove all or list of geofences |
uploadLog |
url:String |
Upload the plugin log to url |
destroyLog |
none | Delete the on-device plugin log |
Examples
Stop the SDK:
{ "background_geolocation": ["stop"] }
Change pace:
{ "background_geolocation": ["changePace", true] }
Update configuration (compound form):
{
"background_geolocation": [
"setConfig",
{
"geolocation": { "distanceFilter": 25, "desiredAccuracy": 3 },
"http": { "autoSync": true, "batchSync": true, "maxBatchSize": 50 }
}
]
}
Examples
Simple configuration (immediate uploads)
import 'package:flutter_background_geolocation/flutter_background_geolocation.dart' as bg;
final config = bg.Config(
http: bg.HttpConfig(
url: 'https://api.example.com/locations',
method: 'POST',
autoSync: true,
batchSync: false,
timeout: 60000,
headers: {'Authorization': 'Bearer secret-token'},
params: {'device_id': 'abc-123'},
),
);
Batched uploads with threshold
final config = bg.Config(
http: bg.HttpConfig(
url: 'https://api.example.com/locations/bulk',
autoSync: true,
batchSync: true,
maxBatchSize: 25,
autoSyncThreshold: 10,
rootProperty: 'locations',
),
);
Conserve cellular data
final config = bg.Config(
http: bg.HttpConfig(
url: 'https://api.example.com/locations',
autoSync: true,
disableAutoSyncOnCellular: true,
),
);
Manual sync
await bg.BackgroundGeolocation.setConfig(bg.Config(
http: bg.HttpConfig(
url: 'https://api.example.com/locations',
autoSync: false,
),
));
await bg.BackgroundGeolocation.sync();
Migration from legacy flat Config
Previously, HTTP parameters were defined directly on Config:
// Legacy
Config(
url: 'https://api.example.com',
autoSync: true,
headers: {'Authorization': 'Bearer ...'},
);
They are now grouped under HttpConfig via Config.http:
// New
Config(
http: HttpConfig(
url: 'https://api.example.com',
autoSync: true,
headers: {'Authorization': 'Bearer ...'},
),
);
Legacy keys remain available but are marked @Deprecated and will be removed in a future major release. Prefer the new compound form.
Constructors
Properties
- autoSync → bool?
-
Immediately upload each recorded location to your configured HttpConfig.url.
final
- autoSyncThreshold → int?
-
The minimum number of persisted records the plugin must accumulate before triggering an HttpConfig.autoSync action.
final
- batchSync → bool?
-
POST multiple locations to your HttpConfig.url in a single HTTP request.
final
- disableAutoSyncOnCellular → bool?
-
Disable HttpConfig.autoSync HTTP requests when device is connected to a Cellular connection.
Defaults to
false. Settrueto allow HttpConfig.autoSync only when device is connected to Wifi.final - hashCode → int
-
The hash code for this object.
no setterinherited
-
headers
→ Map<
String, dynamic> ? -
Optional HTTP headers applied to each HTTP request.
final
- maxBatchSize → int?
-
Controls the number of records attached to each batch HTTP request.
final
- method → String?
-
The HTTP method to use when creating an HTTP request to your configured HttpConfig.url.
final
-
params
→ Map<
String, dynamic> ? -
Optional HTTP
paramsappended to the JSON body of each HTTP request.final - rootProperty → String?
-
The root property of the JSON schema where location-data will be attached.
final
- runtimeType → Type
-
A representation of the runtime type of the object.
no setterinherited
- timeout → int?
-
HTTP request timeout in milliseconds.
final
- url ↔ String?
-
Your server
urlwhere you wish toPOSTlocations to.getter/setter pair
Methods
-
noSuchMethod(
Invocation invocation) → dynamic -
Invoked when a nonexistent method or property is accessed.
inherited
-
toMap(
) → Map< String, dynamic> -
toString(
) → String -
A string representation of this object.
inherited
Operators
-
operator ==(
Object other) → bool -
The equality operator.
inherited