Skip to content
Support the creatorSupport

Config

Pass a Config object to configure() (replace) or setConfig() (merge). Every key is optional.

import LongPing, { type Config } from 'react-native-long-ping';
Call Behaviour
configure(config) Replaces the whole config with the defaults plus config, validates, saves and applies it live. Never starts, stops or prompts. Safe on every launch.
setConfig(partial) Deep-merges into the current config: objects merge, arrays and scalars replace. Validates, saves, applies.
Server reply long_ping.config Stored as a separate layer on top of the app’s config (it survives configure()), applied when remoteConfig is true. long_ping.reset clears it. See Remote config.

Both calls resolve the new State, whose config field holds the full resolved config.

Validation rules:

  • A value of the wrong type rejects with INVALID_CONFIG; the message names the key (for example http.url).
  • Numbers outside their range are clamped into it, not rejected.
  • null on a key that is not nullable means “use the default”. '' on a nullable string means null.
  • Unknown keys are ignored and logged at debug level.
  • http.url must be an absolute http:// or https:// URL.
  • lowBattery needs both fields.
  • A negative minAccuracyM rejects with INVALID_CONFIG.
  • http.locationTemplate is checked by rendering a sample record and parsing the result as JSON; an unknown token or invalid JSON rejects with INVALID_CONFIG.

The config is saved on the device (Android SharedPreferences, iOS UserDefaults). Upload credentials are never part of it; they go through setAuthorization().

{
movingIntervalSec: 30,
parkedIntervalSec: 180,
accuracy: 'high',
minAccuracyM: 100,
stopTimeoutSec: 300,
stopRadiusM: 75,
movingSpeedMps: 3,
disableStopDetection: false,
lowBattery: null,
http: {
url: null,
method: 'POST',
headers: {},
batch: true,
maxBatchSize: 100,
uploadIntervalSec: 0,
rootProperty: null,
locationTemplate: null,
params: {},
extras: {},
timeoutSec: 30,
},
persistence: { maxRecords: 10000, maxDays: 7 },
startOnBoot: true,
stopOnTerminate: false,
remoteConfig: true,
notification: {
title: 'Location tracking',
text: 'Sharing your location',
channelName: 'Location tracking',
smallIcon: null,
priority: 'low',
},
ios: { showsBackgroundLocationIndicator: false, activityType: 'automotive' },
logLevel: 'info',
logMaxDays: 3,
debug: false,
}
Key Type Default Range
movingIntervalSec number 30 1 – 86400
parkedIntervalSec number 180 1 – 86400
lowBattery object | null null see below

movingIntervalSec: seconds between recorded fixes while moving.

parkedIntervalSec: seconds between recorded fixes while parked.

lowBattery: { belowPct: number; intervalSec: number }. When the phone is not charging and the battery is below belowPct percent (0–100), the interval becomes at least intervalSec seconds (1–86400). Both fields are required. null turns it off.

The effective interval is recomputed on every fix, on every motion change, config change and battery change:

base = isMoving ? movingIntervalSec : parkedIntervalSec
if lowBattery != null && !charging && batteryPct < lowBattery.belowPct:
base = max(base, lowBattery.intervalSec)

A fix is recorded when at least interval − tolerance has passed since the last recorded fix, where tolerance is min(0.5 s, 10 % of the interval), so a 10 s interval records a fix every 10 s on both platforms. Motion changes are always recorded immediately. On iOS, intervals of 60 s or more use a low-power mode between fixes; see How iOS background tracking works.

Key Type Default Range
accuracy 'high' | 'balanced' | 'low' 'high'
minAccuracyM number 100 ≥ 0; 0 accepts any accuracy

accuracy sets what the OS is asked for:

Value Android (fused provider priority) iOS (desiredAccuracy when a fix is taken)
'high' PRIORITY_HIGH_ACCURACY kCLLocationAccuracyBest
'balanced' PRIORITY_BALANCED_POWER_ACCURACY kCLLocationAccuracyHundredMeters
'low' PRIORITY_LOW_POWER kCLLocationAccuracyKilometer

minAccuracyM: fixes with a horizontal accuracy worse than this many meters are not recorded. If a fix is overdue (more than interval + 30 s since the last record) and only inaccurate fixes arrived, the most accurate one seen is recorded anyway, and the log says so.

Moving and parked are decided from the fixes (speed and displacement), never from an OS activity classifier. The rules are identical on both platforms.

Key Type Default Range
stopTimeoutSec number 300 30 – 86400
stopRadiusM number 75 10 – 10000
movingSpeedMps number 3 0.5 – 100
disableStopDetection boolean false

stopTimeoutSec: how long the device has to stay within stopRadiusM before it counts as parked.

stopRadiusM: the radius, in meters, that counts as “not going anywhere”. On iOS a region of radius max(100, stopRadiusM × 2) is also monitored while parked; leaving it switches back to moving immediately.

movingSpeedMps: a speed, in meters per second, that counts as moving (3 m/s ≈ 11 km/h ≈ 6.7 mph).

disableStopDetection: true keeps the device in the moving state for as long as tracking is on.

How the state changes:

  • Moving → parked: the device has stayed within stopRadiusM of an anchor fix, below movingSpeedMps, for stopTimeoutSec.
  • Parked → moving: a fix at or above movingSpeedMps with accuracy ≤ 50 m, or a fix more than stopRadiusM from the parked position with accuracy ≤ stopRadiusM.

Only fixes with accuracy ≤ max(minAccuracyM, stopRadiusM) are evaluated. You can force either state with changePace().

Key Type Default Range / values
url string | null null Absolute http(s) URL. null or '' = record only, never upload.
method 'POST' | 'PUT' 'POST'
headers Record<string, string> {} Sent with every upload.
batch boolean true
maxBatchSize number 100 1 – 1000
uploadIntervalSec number 0 0 – 86400
rootProperty string | null null Any key, or '.'
locationTemplate string | null null JSON template with {{tokens}}
params object {} Merged into the body root.
extras object {} Added to every record as extras.
timeoutSec number 30 5 – 120

url: the upload endpoint. Without it, fixes are still recorded, stored and emitted to JavaScript, but nothing is uploaded.

headers: added to every upload. When an access token is stored, Authorization: Bearer <token> is added too and wins over an Authorization header set here.

batch: true sends up to maxBatchSize records per request under locations. false sends one request per record under location.

uploadIntervalSec: 0 uploads as soon as a fix is recorded. N means at most one upload every N seconds. sync() ignores it.

rootProperty: where the records go in the body. null means 'locations' (batch) or 'location' (single). '.' puts a single record’s fields at the body root; with batch: true, '.' falls back to 'locations'.

locationTemplate: replaces the default record JSON, per record. Tokens are replaced with raw JSON values and strings go in without quotes, so write them yourself: '{"lat":{{latitude}},"lng":{{longitude}},"at":"{{timestamp}}"}'. Tokens: uuid, timestamp, event, is_moving, latitude, longitude, accuracy, speed, heading, altitude, battery_level, battery_is_charging, mock, extras (JSON object text).

params: merged into the root of every request body.

extras: added to every record as an extras object (merged with any per-call extras from getCurrentPosition(); the record only has extras when the result is non-empty).

timeoutSec: per request.

The exact request and response rules are in the HTTP contract; try them in the playground in Receiving uploads.

Key Type Default Range
persistence.maxRecords number 10000 1 – 1000000
persistence.maxDays number 7 1 – 365

The on-device queue keeps at most maxRecords records and nothing older than maxDays days. It is pruned after each insert, oldest first, and pruning is logged with counts.

Key Type Default
startOnBoot boolean true
stopOnTerminate boolean false
remoteConfig boolean true

startOnBoot: on Android, tracking that was enabled resumes after a reboot or an app update without the app being opened. With false it waits until the app is opened. On iOS, relaunching after termination comes from significant-change and region monitoring; see How iOS background tracking works.

stopOnTerminate: true stops tracking when the app is terminated (swiped away). With the default false, iOS keeps significant-change and region monitoring on so it can relaunch the app.

remoteConfig: apply long_ping.config from upload replies. Only the app can set it. A long_ping.stop or long_ping.reset from the server is honoured regardless.

The foreground-service notification shown while tracking on Android. Ignored on iOS.

Key Type Default Notes
notification.title string 'Location tracking'
notification.text string 'Sharing your location'
notification.channelName string 'Location tracking' Shown in the app’s notification settings.
notification.smallIcon string | null null A drawable or mipmap resource name. null = the app icon.
notification.priority 'low' | 'default' | 'high' 'low'

On Android 13+ the notification is only visible if your app has POST_NOTIFICATIONS; see Installation.

Key Type Default
ios.showsBackgroundLocationIndicator boolean false
ios.activityType 'automotive' | 'otherNavigation' | 'fitness' | 'other' 'automotive'

showsBackgroundLocationIndicator: show the blue location indicator in the status bar while the app uses location in the background.

activityType: passed to CoreLocation as the activity type.

Key Type Default Range / values
logLevel 'off' | 'error' | 'warn' | 'info' | 'debug' 'info'
logMaxDays number 3 1 – 30
debug boolean false

logLevel and logMaxDays control the on-device log you read with logger.getLog(). See Troubleshooting.

debug: on Android, the notification text shows the age of the last fix and the queue size.