react-native -v): 55.2 desiredAccuracy: 25,
maximumAge: 20000,
samples: 2,
timeout: 20,
distanceFilter: 30,
foregroundService: true,
logLevel: BackgroundGeolocation.LOG_LEVEL_ERROR,
preventSuspend: true,
We're using our own library to send the requests and have validated that the problem isn't there.j
Events with identical cooridinates are rarely generated
We're seeing location events coming through with identical coordinates. This is only on devices out in the wild and we can't reproduce on our test devices, so this is more of a question rather than a bug report.
Sometimes the timespan between the events is milliseconds and other times it's hours. They're not always sequential either and we're seeing instances across iOS and Android.
What are the conditions required for the device to report the same lat/lng coordinates? I'd assume that would be very rare and tried doing some research but couldn't find anything concrete. We do have a maxAge on getCurrentPosition, but it's only set to 20s. Is there any other valid reason where that method would return coordinates that have been sent previously?
N/A
It's worth mentioning we use background location tracking and getCurrentPosition, triggered on certain app actions.
Have asked affected users to submit email logs. Will attach as and when they come through.
I have attached a csv example of events recorded in our database. Not sure it will help, but might be relevant.
There's no possible way you experience this on both iOS AND Android.
The plugin posts a uuid string with each location. You can use this to detect if the plugin posts an actual duplicate location.
Show me plugin logs where this occurs (with exact timestamp when it occurred).
Be default, the Android plugin filters out duplicate locations relative to last recorded location like this:
private boolean locationSameAsLast(Location l) {
if (lastLocation == null) {
return false;
} else if (lastLocation == l) {
return true;
} else if (
(l.getLatitude() == lastLocation.getLatitude()) &&
(l.getLongitude() == lastLocation.getLongitude()) &&
(l.getSpeed() == lastLocation.getSpeed()) &&
(l.getBearing() == lastLocation.getBearing())
) {
return true;
} else {
return false;
}
}
The plugin posts a uuid string with each location. You can use this to detect if the plugin posts an actual duplicate location.
Ah cool, we don't record that but that's a useful data point we can definitely collect.
Show me plugin logs where this occurs (with exact timestamp when it occurred).
Still waiting on these as it's a manual request from user side. Will post when we have some.
Thanks for the help @christocracy
@christocracy We've published an update to our app to record the uuid of events, so that should hopefully give us some good insights. In the meantime, we got some logs back from users and the only thing of note in there is a few occurrences of:
09-28 20:32:01.492 ERROR [TSLocationManager getLastLocation]
βΌοΈ Failed to get last location: com.google.android.gms.tasks.zzp@f49093b
Is that a common log or something to look into? I haven't been able to align this to an instance of the duplicates yet which might tell us if that's related.
Itβs not a big deal. The native location apis hold a reference to the last known location.
There was none in this case. It can happen at boot before the location apis lock in and fetch a location.
And do testing on a variety of devices if possible.
If you install and run the demo app in parallel, you can easily add geofences in the βAdvanced Appβ by long-pressing on the map.
Add 3 or 4 geofences within a kilometer and go for a walk.
@christocracy I've managed to get a stream of data highlighting the issue. I'm still skeptical that it's anything to do with RNBG, but I'm just posting in case anything obvious jumps out.
The only interesting thing about this set of events is that the user didn't have a solid network connection (or network was off) at the time they were recorded. We know this because we keep a reference to device timestamp and server timestamp. We process events ourselves and we've ran through the logic and can't find anything in our own code.
As network was offline, I'm wondering if that also means they didn't have other services like location available at the time. We did try disabling location services while debugging and as expected it didn't report any gps events. Could network connection have any impact on gps? I'm still interested in whether it's plausible to get identical GPS coordinates depending on location service settings, e.g. if it's just relying on wifi/cell-tower positioning. We couldn't replicate that either though, the coordinates were always consistently unique.
I've attached the data we've pulled, here's some context:
As I said, I'm not expecting any answers just posting in case anything obvious jumps out. Our next steps are to go through debugging steps again with the demo app side-loaded and also try and determine if there's any correlation between the different duplicate coordinates. Will keep the thread updated with any findings
@christocracy Just to check, if I call getCurrentPosition multiple times within the maximumAge period, then should the timestamp the module supplies me the same for all those calls? i.e. uuid is different, timestamp is from original and obviously coordinates the same
yes.
@christocracy So I've been able to reproduce a couple of scenarios which don't fully explain the issues we're having, but are interesting anyway:
I was able to get the module to fire multiple GPS events with the same coordinates within the maximumAge duration of the last event by repeatedly making calls to getCurrentPosition in a short period of time. For context, we request current position when certain scenes are opened, so to replicate I could quickly enter and exit those scenes. If you don't do it fast it behaves as advertised and filters the duplicates. Here's the log:
ββββββββββββββββββββββββββββββββββββββββββββββ
β LocationService: location:1008
β βββββββββββββββββββββββββββββββββββββββββββββ
ββ π Location[fused -37.797806,144.986289 hAcc=106 et=+5d13h56m14s716ms alt=35.139691597985625 vel=1.1555142 bear=313.0 vAcc=256 sAcc=??? bAcc=??? {Bundle[{battery_level=0.41, uuid=7643a0f4-a036-4c31-8935-02507afb6bf5, requestId=1008, is_charging=true, verticalAccuracy=256.0}]}], age: 104ms
10-12 15:14:33.295 INFO [TSLocationManager onSingleLocationResult]
π΅ Acquired current position
10-12 15:14:33.309 DEBUG [TSLocationManager calculateMedianAccuracy] 128.0
10-12 15:14:33.351 INFO [SQLiteLocationDAO persist]
β
INSERT: 7643a0f4-a036-4c31-8935-02507afb6bf5
10-12 15:14:33.358 DEBUG [LocationService onLocation]
ββββββββββββββββββββββββββββββββββββββββββββββ
β LocationService: location:1007
β βββββββββββββββββββββββββββββββββββββββββββββ
ββ π Location[fused -37.797806,144.986289 hAcc=106 et=+5d13h56m14s716ms alt=35.139691597985625 vel=1.1555142 bear=313.0 vAcc=256 sAcc=??? bAcc=??? {Bundle[{battery_level=0.41, uuid=2264a638-1a1c-4dcc-901c-aa1d3066dbfa, requestId=1007, is_charging=true, verticalAccuracy=256.0}]}], age: 22ms
10-12 15:14:33.375 INFO [TSLocationManager onSingleLocationResult]
π΅ Acquired current position
10-12 15:14:33.383 DEBUG [TSLocationManager calculateMedianAccuracy] 128.0
10-12 15:14:33.412 INFO [SQLiteLocationDAO persist]
β
INSERT: 2264a638-1a1c-4dcc-901c-aa1d3066dbfa
10-12 15:14:33.417 DEBUG [LocationService onLocation]
ββββββββββββββββββββββββββββββββββββββββββββββ
β LocationService: location:1009
β βββββββββββββββββββββββββββββββββββββββββββββ
ββ π Location[fused -37.797806,144.986289 hAcc=106 et=+5d13h56m14s716ms alt=35.139691597985625 vel=1.1555142 bear=313.0 vAcc=256 sAcc=??? bAcc=??? {Bundle[{battery_level=0.41, uuid=915057e8-b349-4bfd-9578-eeb0946f533a, requestId=1009, is_charging=true, verticalAccuracy=256.0}]}], age: 38ms
10-12 15:14:33.457 INFO [TSLocationManager onSingleLocationResult]
π΅ Acquired current position
10-12 15:14:33.470 DEBUG [TSLocationManager calculateMedianAccuracy] 117.132
10-12 15:14:33.493 INFO [SQLiteLocationDAO persist]
β
INSERT: 915057e8-b349-4bfd-9578-eeb0946f533a
We've only seen a couple of these in the wild and it's not a huge deal, but I was able to replicate the module giving me two identical events in sequence by doing the following:
getCurrentPositionI think the module gives one last location when turning off location services, but it is the same uuid/timestamp/coordinates. Here's the log for that with the dupe insert:
ββββββββββββββββββββββββββββββββββββββββββββββ
β LocationService: location:1027
β βββββββββββββββββββββββββββββββββββββββββββββ
ββ π Location[fused -37.798254,144.986575 hAcc=79 et=+5d14h8m46s156ms alt=51.311688016754566 vel=0.061444677 bear=293.0 vAcc=256 sAcc=??? bAcc=??? {Bundle[{battery_level=0.41, uuid=d779b02b-403d-420c-ab33-1eaf025b5075, requestId=1027, is_charging=true, verticalAccuracy=256.0}]}], age: 18ms
10-12 15:27:04.813 INFO [TSLocationManager onSingleLocationResult]
π΅ Acquired current position
10-12 15:27:04.830 DEBUG [TSLocationManager calculateMedianAccuracy] 79.432
10-12 15:27:04.881 INFO [SQLiteLocationDAO persist]
β
INSERT: d779b02b-403d-420c-ab33-1eaf025b5075
10-12 15:27:30.771 INFO [LocationService onLocation]
βΉοΈ Location availability: true
10-12 15:27:37.461 INFO [LocationService onLocation]
βΉοΈ Location availability: false
10-12 15:27:44.178 INFO [BackgroundGeolocation$n onReceive]
ββββββββββββββββββββββββββββββββββββββββββββββ
β Location-provider change: false
β βββββββββββββββββββββββββββββββββββββββββββββ
ββ GPS: false
ββ Network: false
10-12 15:27:44.201 INFO [TSLocationManager onSingleLocationResult]
π΅ Acquired providerchange position
10-12 15:27:44.215 DEBUG [TSLocationManager calculateMedianAccuracy] 79.24
10-12 15:27:44.240 INFO [SQLiteLocationDAO persist]
β
INSERT: d779b02b-403d-420c-ab33-1eaf025b5075
10-12 15:27:50.312 WARN [SingleLocationRequest finish]
β οΈ timeout: 1028
10-12 15:27:50.354 WARN [TSLocationManager onLocationTimeout]
β οΈ TSLocationManager received location timeout
10-12 15:27:50.370 WARN [BackgroundGeolocation _onLocationError]
β οΈ Location error: 408
I think I saw this a couple of times outside of this in testing but this is the only way I could reproduce consistently
I think this might be intentional, but when requesting getCurrentLocation android won't trigger a new event if it falls within maximumAge, but iOS will (with a different uuid). Again not a huge deal as we can filter ourselves but it's a behaviour difference between platforms.
Let me know if those are useful or not. We're still struggling to identify why a device would trigger duplicate coordinates over a long period of time but the sequential ones we can mitigate. We're going to add a throttle on the getCurrentPosition call and also do our own filtering which should hopefully cover off most of our issues.
@christocracy did you get chance to look at my previous message?
I was able to get the module to fire multiple GPS events with the same coordinates within the maximumAge
I don't understand your problem here. Requesting 3 locations within a few milliseconds is nearly guaranteed to give you the same coords.
The case #2 doesn't really apply. This is a special case where a providerchange event occurs without access to location-services. The Android plugin automatically records a location where the device was when the providerchange event occurred. When location-services is completely disabled, obviously fetching the current location is impossible so the plugin does the best it can and applies the last known location to the event.
However, perhaps I should re-generate the uuid to make it unique. It will still have identical coordinates to some previous location.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. You may also mark this issue as a "discussion" and I will leave this open.
Closing this issue after a prolonged period of inactivity. Fell free to reopen this issue, if this still affecting you.
Be default, the Android plugin filters out duplicate locations relative to last recorded location like
@christocracy - Is this filtering out of duplicate locations also applicable in case of time based tracking ? i.e. when distanceFilter : 0