[Geolocation] watchPosition callback has very unpredictable frequency #1240

Closed
opolyo01 opened this Issue May 11, 2015 · 25 comments

Comments

Projects
None yet
@opolyo01

I am building an app that updates the distance from current location, but for some reason I am not getting a consistent callback frequency for navigator.geolocation.watchPosition
It seems like something reseting the watch. My code has only componentWillUnmount where it would reset, but I put Alert it never occurred.

Is there frequency parameter I can specify or I guess I am thinking to go with manual timeout approach.

componentDidMount(){
    AsyncStorage.getItem('listings')
      .then((value) => {
        this.state.listings = value?JSON.parse(value):[];
        this.state.passProps.listings = this.state.listings;
        this.redrawListings();
        this.startWatch();
      })
      .done();
  }

  componentWillUnmount(){
    navigator.geolocation.clearWatch(this.watchID);
  }
startWatch(){
    this.watchID = navigator.geolocation.watchPosition((lastPosition) => {
      this.curLat = lastPosition.coords.latitude;
      this.curLon = lastPosition.coords.longitude;
      this._updateDistances();
    },
    (error) => AlertIOS.alert(error),
    {enableHighAccuracy: true, timeout: 0, maximumAge: 1000});
  }

@brentvatne brentvatne changed the title from Geo: watchPosition callback has very unpredictable frequency to [Geolocation] watchPosition callback has very unpredictable frequency May 30, 2015

@brentvatne

This comment has been minimized.

Show comment
Hide comment
@brentvatne

brentvatne May 30, 2015

Collaborator

@opolyo01 - the geolocation module uses CALocationManager, and the startUpdatingLocation method when you call watchPosition.

From the docs on it:

Calling this method causes the location manager to obtain an initial location fix (which may take several seconds) and notify your delegate by calling its locationManager:didUpdateLocations: method. (In iOS 5 and earlier, the location manager calls the locationManager:didUpdateToLocation:fromLocation: method instead.) After that, the receiver generates update events primarily when the value in the distanceFilter property is exceeded. Updates may be delivered in other situations though. For example, the receiver may send another notification if the hardware gathers a more accurate location reading.

distanceFilter is set to kCLLocationAccuracyHundredMeters - if you were to set it to kCLLocationAccuracyTenMeters you would receive updates more frequently.

It might make sense to have this be configurable, but you'll have to keep in mind that greater degrees of accuracy result in higher battery usage. Any reason not to expose this @nicklockwood?

If you'd like to get the updates every x seconds, then just setting a timeout and grabbing the current location would be okay.

Collaborator

brentvatne commented May 30, 2015

@opolyo01 - the geolocation module uses CALocationManager, and the startUpdatingLocation method when you call watchPosition.

From the docs on it:

Calling this method causes the location manager to obtain an initial location fix (which may take several seconds) and notify your delegate by calling its locationManager:didUpdateLocations: method. (In iOS 5 and earlier, the location manager calls the locationManager:didUpdateToLocation:fromLocation: method instead.) After that, the receiver generates update events primarily when the value in the distanceFilter property is exceeded. Updates may be delivered in other situations though. For example, the receiver may send another notification if the hardware gathers a more accurate location reading.

distanceFilter is set to kCLLocationAccuracyHundredMeters - if you were to set it to kCLLocationAccuracyTenMeters you would receive updates more frequently.

It might make sense to have this be configurable, but you'll have to keep in mind that greater degrees of accuracy result in higher battery usage. Any reason not to expose this @nicklockwood?

If you'd like to get the updates every x seconds, then just setting a timeout and grabbing the current location would be okay.

@brentvatne brentvatne self-assigned this May 30, 2015

@nicklockwood

This comment has been minimized.

Show comment
Hide comment
@nicklockwood

nicklockwood May 30, 2015

Contributor

There's no reason not to expose the accuracy, but it should be done so in a way that's compliant with the HTML5 Geolocation API as far as possible.

I thought we already did this, but I guess I misremembered.

Contributor

nicklockwood commented May 30, 2015

There's no reason not to expose the accuracy, but it should be done so in a way that's compliant with the HTML5 Geolocation API as far as possible.

I thought we already did this, but I guess I misremembered.

@brentvatne

This comment has been minimized.

Show comment
Hide comment
@brentvatne

brentvatne May 30, 2015

Collaborator

@nicklockwood - poor wording on my behalf - desiredAccuracy is exposed, distanceFilter is not

Collaborator

brentvatne commented May 30, 2015

@nicklockwood - poor wording on my behalf - desiredAccuracy is exposed, distanceFilter is not

@brentvatne brentvatne removed their assignment Sep 20, 2015

@grabbou

This comment has been minimized.

Show comment
Hide comment
@grabbou

grabbou Oct 2, 2015

Collaborator

What about monitoring significant updates only? It feels like the most reasonable approach would've been to implement own geolocation where HTML5 compliancy does not matter.

Collaborator

grabbou commented Oct 2, 2015

What about monitoring significant updates only? It feels like the most reasonable approach would've been to implement own geolocation where HTML5 compliancy does not matter.

@chris-erickson

This comment has been minimized.

Show comment
Hide comment
@chris-erickson

chris-erickson Oct 28, 2015

It would be useful to expose this API more completely. After a basic look into it, we seem to be missing a large amount of control over the location API when making it comply with HTML5. Perhaps I'm wrong, that's my initial take as I work through using this.

It would be useful to expose this API more completely. After a basic look into it, we seem to be missing a large amount of control over the location API when making it comply with HTML5. Perhaps I'm wrong, that's my initial take as I work through using this.

@yonahforst

This comment has been minimized.

Show comment
Hide comment
@yonahforst

yonahforst Feb 11, 2016

@christopherdro I've upgraded to rn 0.20.0-rc1 which should include your update, right? I'm still experiencing a similar issue, where I only get location updates once every ~25 seconds. Even using the following options: {enableHighAccuracy: true, distanceFilter: 1, timeout: 1000}

@christopherdro I've upgraded to rn 0.20.0-rc1 which should include your update, right? I'm still experiencing a similar issue, where I only get location updates once every ~25 seconds. Even using the following options: {enableHighAccuracy: true, distanceFilter: 1, timeout: 1000}

@christopherdro

This comment has been minimized.

Show comment
Hide comment
@christopherdro

christopherdro Feb 11, 2016

Contributor

@joshblour Are you testing in iOS or Android. Did you try setting distance filter to 10 and see if that changes anything?

Contributor

christopherdro commented Feb 11, 2016

@joshblour Are you testing in iOS or Android. Did you try setting distance filter to 10 and see if that changes anything?

@rt2zz

This comment has been minimized.

Show comment
Hide comment
@rt2zz

rt2zz Feb 11, 2016

Contributor

@joshblour @christopherdro the distanceFilter commit was merged master but has not landed in any release yet. You might consider cherry picking #5563 in the meantime.

Contributor

rt2zz commented Feb 11, 2016

@joshblour @christopherdro the distanceFilter commit was merged master but has not landed in any release yet. You might consider cherry picking #5563 in the meantime.

@christopherdro

This comment has been minimized.

Show comment
Hide comment
@christopherdro

christopherdro Feb 11, 2016

Contributor

@rt2zz Thanks for checking on that!
@joshblour This would be the commit to cherry pick. 109036b

Contributor

christopherdro commented Feb 11, 2016

@rt2zz Thanks for checking on that!
@joshblour This would be the commit to cherry pick. 109036b

@npomfret

This comment has been minimized.

Show comment
Hide comment
@npomfret

npomfret Apr 20, 2016

Contributor

Do navigator.geolocation.getCurrentPosition work and navigator.geolocation.watchPosition work on android? I'm just getting a timeout error. I've got <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />in my manifest file, and I can see the users current position (the blue dot) on a map, but I can't programatically get the position.

Contributor

npomfret commented Apr 20, 2016

Do navigator.geolocation.getCurrentPosition work and navigator.geolocation.watchPosition work on android? I'm just getting a timeout error. I've got <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />in my manifest file, and I can see the users current position (the blue dot) on a map, but I can't programatically get the position.

@dominicmh

This comment has been minimized.

Show comment
Hide comment
@dominicmh

dominicmh May 9, 2016

Is it possible distanceFilter is completely ignored on iOS? I've set it to a ridiculously high number but the callback is triggered very frequently without any or just small change in the coordinates.

Is it possible distanceFilter is completely ignored on iOS? I've set it to a ridiculously high number but the callback is triggered very frequently without any or just small change in the coordinates.

@bjonamu

This comment has been minimized.

Show comment
Hide comment
@bjonamu

bjonamu May 17, 2016

I am having the same issue as @dominicmh. On Android the distanceFilter option seems to be also ignored and I get responses every 20 seconds. I would really like to only update my location when it changes by 5 meters. Does anyone know how to achieve this? My code is as below

this.watchID = navigator.geolocation.watchPosition((pos)=>{
   var crd = pos.coords;
   this.updateLocation(crd.latitude, crd.longitude);
},
{enableHighAccuracy: true, timeout: 1000, maximumAge: 0,distanceFilter:5});

I even tried setting the distanceFilter to something crazy like 200 but it still updates every 20s

bjonamu commented May 17, 2016

I am having the same issue as @dominicmh. On Android the distanceFilter option seems to be also ignored and I get responses every 20 seconds. I would really like to only update my location when it changes by 5 meters. Does anyone know how to achieve this? My code is as below

this.watchID = navigator.geolocation.watchPosition((pos)=>{
   var crd = pos.coords;
   this.updateLocation(crd.latitude, crd.longitude);
},
{enableHighAccuracy: true, timeout: 1000, maximumAge: 0,distanceFilter:5});

I even tried setting the distanceFilter to something crazy like 200 but it still updates every 20s

@quatrix

This comment has been minimized.

Show comment
Hide comment
@quatrix

quatrix Jun 2, 2016

distanceFilter seems to be ignored for me too (ios, latest React from npm)

quatrix commented Jun 2, 2016

distanceFilter seems to be ignored for me too (ios, latest React from npm)

@christopherdro

This comment has been minimized.

Show comment
Hide comment
@christopherdro

christopherdro Jun 2, 2016

Contributor

@quatrix This got recently merged and might be worth looking into.
#6987

Contributor

christopherdro commented Jun 2, 2016

@quatrix This got recently merged and might be worth looking into.
#6987

@npomfret

This comment has been minimized.

Show comment
Hide comment
@npomfret

npomfret Dec 21, 2016

Contributor

I still can't get updates at the frequency I want. When I use react-native-maps and turn on the showsUserLocation option the blue dot moves around with a much greater frequency than my watchPosition gets called. Any idea why?

Contributor

npomfret commented Dec 21, 2016

I still can't get updates at the frequency I want. When I use react-native-maps and turn on the showsUserLocation option the blue dot moves around with a much greater frequency than my watchPosition gets called. Any idea why?

@willyyang

This comment has been minimized.

Show comment
Hide comment
@willyyang

willyyang Jan 19, 2017

@Jonrock23 did you ever figure out how to only get the updated locations once it's changed by 5 metres?

@Jonrock23 did you ever figure out how to only get the updated locations once it's changed by 5 metres?

@Larney11

This comment has been minimized.

Show comment
Hide comment
@Larney11

Larney11 Feb 3, 2017

@christopherdro I am having the same issue for IOS. Has this issue you resolved only work for android?

It says in the react-native-background-geolocation repo:

  • on iOS, background tracking won't be engaged until you travel about 2-3 city blocks
  • Android is much quicker detecting movements; typically several meters of walking will do it.

Can anyone tell me if this is still the case?
Any insight is greatly appreciated.

Larney11 commented Feb 3, 2017

@christopherdro I am having the same issue for IOS. Has this issue you resolved only work for android?

It says in the react-native-background-geolocation repo:

  • on iOS, background tracking won't be engaged until you travel about 2-3 city blocks
  • Android is much quicker detecting movements; typically several meters of walking will do it.

Can anyone tell me if this is still the case?
Any insight is greatly appreciated.

@Larney11

This comment has been minimized.

Show comment
Hide comment
@Larney11

Larney11 Feb 3, 2017

@npomfret @willyyang Are you having this problem for IOS or Android?

Larney11 commented Feb 3, 2017

@npomfret @willyyang Are you having this problem for IOS or Android?

@npomfret

This comment has been minimized.

Show comment
Hide comment
@npomfret

npomfret Feb 4, 2017

Contributor

I'm having the problem on iOS. If I use react-native-maps I see the blue user dot moving around with great frequency, but the calls backs my RN app sees aren't anyway near as frequent.

Contributor

npomfret commented Feb 4, 2017

I'm having the problem on iOS. If I use react-native-maps I see the blue user dot moving around with great frequency, but the calls backs my RN app sees aren't anyway near as frequent.

@Larney11

This comment has been minimized.

Show comment
Hide comment
@Larney11

Larney11 Feb 4, 2017

Thanks. I'm going to see what its like for android.

Larney11 commented Feb 4, 2017

Thanks. I'm going to see what its like for android.

@brucepom

This comment has been minimized.

Show comment
Hide comment
@brucepom

brucepom Feb 17, 2017

I'm experiencing the issue where location updates are triggered every ~100m even if I set distanceFilter to a lower value. I've done some troubleshooting and I think the issue I'm experiencing is related to these lines: https://github.com/facebook/react-native/blob/0.42-stable/Libraries/Geolocation/RCTLocationObserver.m#L309-L311.
I'm still working on it and hope to be able to provide some more detail. But I believe for me those lines are causing to be reset back to it's default distanceFilter value of kCLLocationAccuracyHundredMeters.

I'm experiencing the issue where location updates are triggered every ~100m even if I set distanceFilter to a lower value. I've done some troubleshooting and I think the issue I'm experiencing is related to these lines: https://github.com/facebook/react-native/blob/0.42-stable/Libraries/Geolocation/RCTLocationObserver.m#L309-L311.
I'm still working on it and hope to be able to provide some more detail. But I believe for me those lines are causing to be reset back to it's default distanceFilter value of kCLLocationAccuracyHundredMeters.

@Larney11

This comment has been minimized.

Show comment
Hide comment
@Larney11

Larney11 Feb 19, 2017

My solution was to call the "navigator.geolocation.getCurrentPosition" function inside a "setInterval" function.

My solution was to call the "navigator.geolocation.getCurrentPosition" function inside a "setInterval" function.

@npomfret

This comment has been minimized.

Show comment
Hide comment
@npomfret

npomfret Feb 20, 2017

Contributor

The timeout parameter is working for me now, I'm getting much more frequent updates by setting it to 250 (ms).

Contributor

npomfret commented Feb 20, 2017

The timeout parameter is working for me now, I'm getting much more frequent updates by setting it to 250 (ms).

@lsei

This comment has been minimized.

Show comment
Hide comment
@lsei

lsei Mar 21, 2017

I'm using the following options for watchPosition and have managed to get pretty frequent updates in iOS Simulator and built onto my iPhone (RN 0.42.3):

{
    enableHighAccuracy: true,
    distanceFilter: 1,
}

lsei commented Mar 21, 2017

I'm using the following options for watchPosition and have managed to get pretty frequent updates in iOS Simulator and built onto my iPhone (RN 0.42.3):

{
    enableHighAccuracy: true,
    distanceFilter: 1,
}
@Larney11

This comment has been minimized.

Show comment
Hide comment
@Larney11

Larney11 Apr 13, 2017

@Isei How frequent is it, as in how much metres do you travel for it to return locations? Just asking because if you're zoomed out it appears to be accurate but the more you zoom in you realise how inaccurate it is.

@Isei How frequent is it, as in how much metres do you travel for it to return locations? Just asking because if you're zoomed out it appears to be accurate but the more you zoom in you realise how inaccurate it is.

@facebook facebook locked as resolved and limited conversation to collaborators Jul 22, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.