transistorsoft / react-native-background-geolocation

Sophisticated, battery-conscious background-geolocation with motion-detection
http://shop.transistorsoft.com/pages/react-native-background-geolocation
MIT License
2.54k stars 424 forks source link

registerHeadlessTask coords template issue #2004

Open superyarik opened 3 weeks ago

superyarik commented 3 weeks ago

Your Environment

╔═════════════════════════════════════════════ ║ TSLocationManager3.5.1 (430) ╠═════════════════════════════════════════════ ╟─ samsung SM-G990B @ 14 (react) { "activityRecognitionInterval": 10000, "allowIdenticalLocations": false, "authorization": {}, "autoSync": true, "autoSyncThreshold": 20, "backgroundPermissionRationale": { "title": "##", "message": "##", "positiveAction": "##", "negativeAction": "##" }, "batchSync": true, "configUrl": "", "debug": false, "deferTime": 0, "desiredAccuracy": -1, "desiredOdometerAccuracy": 100, "disableAutoSyncOnCellular": false, "disableElasticity": false, "disableLocationAuthorizationAlert": true, "disableMotionActivityUpdates": false, "disableProviderChangeRecord": true, "disableStopDetection": false, "distanceFilter": 50, "elasticityMultiplier": 1, "enableHeadless": true, "enableTimestampMeta": false, "extras": {}, "fastestLocationUpdateInterval": -1, "foregroundService": true, "geofenceInitialTriggerEntry": true, "geofenceModeHighAccuracy": false, "geofenceProximityRadius": 1000, "geofenceTemplate": "", "headers": { "X-APPLICATION-ID": "1", "Accept": "application\/json", "X-AGENT": "android", "X-CLIENT-IDENTIFIER": "768173d2-b46c-561c-991c-e9c7a369081b", "X-CLIENT-UTC-OFFSET": "180", "Content-Type": "application\/json", "Accept-Language": "ru-RU" }, "headlessJobService": "com.transistorsoft.rnbackgroundgeolocation.HeadlessTask", "heartbeatInterval": 60, "httpRootProperty": ".", "httpTimeout": 60000, "isMoving": false, "locationAuthorizationRequest": "Always", "locationTemplate": "{\n \"Coordinate\": \"<%= latitude %>:<%= longitude %>\",\n \"Altitude\": <%= altitude %>,\n \"Accuracy\": <%= accuracy %>,\n \"Speed\": <%= speed %>,\n \"Bearing\": <%= heading %>,\n \"is_mocked\": <%= mock %>,\n \"ClientTimestamp\": \"<%= timestamp %>\"\n }", "locationTimeout": 60, "locationUpdateInterval": 30000, "locationsOrderDirection": "ASC", "logLevel": 5, "logMaxDays": 3, "maxBatchSize": -1, "maxDaysToPersist": 60, "maxMonitoredGeofences": 97, "maxRecordsToPersist": -1, "method": "POST", "minimumActivityRecognitionConfidence": 75, "motionTriggerDelay": 0, "notification": { "layout": "", "title": "##", "text": "##", "color": "", "channelName": "##", "channelId": "##", "smallIcon": "", "largeIcon": "", "priority": -1, "sticky": false, "strings": {}, "actions": [] }, "params": {}, "persist": true, "persistMode": 2, "schedule": [], "scheduleUseAlarmManager": false, "speedJumpFilter": 300, "startOnBoot": true, "stationaryRadius": 25, "stopAfterElapsedMinutes": 0, "stopOnStationary": false, "stopOnTerminate": false, "stopTimeout": 5, "triggerActivities": "in_vehicle, on_bicycle, on_foot, running, walking", "url": "##", "useSignificantChangesOnly": false, "enabled": true, "schedulerEnabled": false, "trackingMode": 1, "odometer": 1382863.875, "isFirstBoot": false, "didLaunchInBackground": false, "didDeviceReboot": false } ╔═════════════════════════════════════════════ ║ DEVICE SENSORS ╠═════════════════════════════════════════════ ╟─ ✅ ACCELEROMETER: {Sensor name="LSM6DSO Accelerometer", vendor="STMicro", version=15933, type=1, maxRange=78.4532, resolution=0.0023928226, power=0.17, minDelay=2404} ╟─ ✅ GYROSCOPE: {Sensor name="LSM6DSO Gyroscope", vendor="STMicro", version=15933, type=4, maxRange=17.453018, resolution=6.108648E-4, power=0.55, minDelay=2404} ╟─ ✅ MAGNETOMETER: {Sensor name="AK09918 Magnetometer", vendor="akm", version=146966, type=2, maxRange=4912.0503, resolution=0.15, power=1.1, minDelay=10000} ╟─ ✅ SIGNIFICANT_MOTION: {Sensor name="smd Wakeup", vendor="Samsung", version=1, type=17, maxRange=1.0, resolution=1.0, power=0.001, minDelay=-1} ╚═════════════════════════════════════════════


## Actual Behavior
While the server for receiving coordinates was unavailable, a certain amount of coordinates accumulated in the phone, awaiting to be sent, and among them contrary to the pattern, there were entries of this type:
```javascript 
{
    "is_moving": false,
    "uuid": "36c76cce-0052-4ddb-bb84-1ab6457a7f8d",
    "timestamp": "2024-04-20T20:05:39.968Z",
    "age": 1124,
    "odometer": 60378.8,
    "coords": {
        "latitude": 67.6016883,
        "longitude": 33.7267389,
        "accuracy": 11.6,
        "speed": 0.09,
        "speed_accuracy": 1.5,
        "heading": -1,
        "heading_accuracy": -1,
        "altitude": 852.8,
        "ellipsoidal_altitude": 852.8,
        "altitude_accuracy": 0.9,
        "age": 1127
    },
    "activity": {
        "type": "still",
        "confidence": 100
    },
    "battery": {
        "is_charging": false,
        "level": 0.86
    },
    "extras": {
        "headless": true
    }
}

Out of approximately 9000 points, only 3 violated the pattern. This is quite critical, as the plugin tries to send all points at once, and the server anticipates a specific format of points, resulting in an error and the points queue builds up until it is cleared, which is not very good as the movement data will be lost.

All 3 points, judging by the extra, came from an event registered through BackgroundGeolocation.registerHeadlessTask, here is the callback itself

BackgroundGeolocation.registerHeadlessTask(backgroundGeolocationHeadlessTask);
...
export const backgroundGeolocationHeadlessTask = async (event) => {
    try {
        const { name } = event;
        switch (name) {
            case 'heartbeat':
                await getCurrentPosition({
                    samples: 3,
                    maximumAge: 5000,
                    extras: {
                        headless: true,
                    },
                });
                break;
            default:
        }
    } catch (error) {
        console.log('backgroundGeolocationHeadlessTask error', error);
    }
};

It's worth noting that all other firings of this callback are correct, the template was successfully applied to them. How can one avoid getting such points in the send queue?

Debug logs

Logs ``` too big to include here https://drive.google.com/file/d/1nTpxrVEsCDA3tK6609iBm6iCY_bkd5n1/view?usp=sharing ```
superyarik commented 2 weeks ago

@christocracy i can also provide list of 9000 collected points