expo icon indicating copy to clipboard operation
expo copied to clipboard

Location.getCurrentPositionAsync() sometimes never responds or takes a very long time to respond

Open rvieceli opened this issue 3 years ago • 107 comments

🐛 Bug Report

I have slow performance on iOS (14), using Expo App (simulator - 11 and real device - 6s) or Standalone (real device - 6s).

Tried to add accuracy to Lowest, but I had same issue.

Works fine on Android.

Environment - output of expo diagnostics & the platform(s) you're targeting

Expo CLI 3.27.12 environment info:
    System:
      OS: macOS 10.15.7
      Shell: 5.7.1 - /bin/zsh
    Binaries:
      Node: 12.13.1 - ~/.nvm/versions/node/v12.13.1/bin/node
      Yarn: 1.22.5 - /usr/local/bin/yarn
      npm: 6.12.1 - ~/.nvm/versions/node/v12.13.1/bin/npm
      Watchman: 4.9.0 - /usr/local/bin/watchman
    Managers:
      CocoaPods: 1.9.3 - /usr/local/bin/pod
    SDKs:
      iOS SDK:
        Platforms: iOS 14.0, DriverKit 19.0, macOS 10.15, tvOS 14.0, watchOS 7.0
      Android SDK:
        API Levels: 28
        Build Tools: 30.0.2
        System Images: android-29 | Google Play Intel x86 Atom
    IDEs:
      Android Studio: 4.0 AI-193.6911.18.40.6626763
      Xcode: 12.0.1/12A7300 - /usr/bin/xcodebuild
    npmPackages:
      @expo/webpack-config: ^0.12.16 => 0.12.37 
      expo: ^39.0.3 => 39.0.3 
      react: 16.13.1 => 16.13.1 
      react-dom: 16.13.1 => 16.13.1 
      react-native: https://github.com/expo/react-native/archive/sdk-39.0.3.tar.gz => 0.63.2 
      react-native-web: ~0.13.14 => 0.13.14 
    npmGlobalPackages:
      expo-cli: 3.27.12
    Expo Workflow: managed

Reproducible Demo

import * as Location from 'expo-location';

async function getLocation() {
  const start = Date.now();
  await Location.getCurrentLocationAsync();
  console.log(Date.now() - start); // consistently around 10,100ms
}

Snack reproducible demo -> https://snack.expo.io/@rvieceli/expo-issue-10756

rvieceli avatar Oct 21 '20 15:10 rvieceli

Hey @rvieceli, you mention this occurred after upgrading...have you been able to reproduce this with a newly created SDK39 project as well?

AdamJNavarro avatar Oct 21 '20 17:10 AdamJNavarro

@AdamJNavarro I'm wrong. We got this issue after upgrade to SDK39 in standalone QA app, but I done right now a test in production with SDK38 and I had the same issue. Maybe is related with iOS14. I'm trying to download a iOS 13 simulator, but my internet don't help me.

rvieceli avatar Oct 21 '20 17:10 rvieceli

@AdamJNavarro We tested with Iphone 11 (ios14) and iphone 6 (ios12) and in both cases in SDK38 (prod) are fast, but in SDK39 (qa) are slow.

rvieceli avatar Oct 21 '20 21:10 rvieceli

@AdamJNavarro We discovery more things during the investigation.

When Precise Location is OFF, SDK 38 and 39 are very slow, if we turn ON works fine in SDK38, but SDK39 is slow.

image

rvieceli avatar Oct 22 '20 10:10 rvieceli

I'm 100% sure if is related, but after our test in SDK38, we got this error in sentry Cannot obtain current location: Error Domain=kCLErrorDomain Code=0 "(null)" We don't have anything in QA sentry with SDK 39.

rvieceli avatar Oct 23 '20 09:10 rvieceli

Try set accuracy low as below:

const location = await Location.getCurrentPositionAsync({ accuracy: isAndroid ? Location.Accuracy.Low : Location.Accuracy.Lowest, })

I set Location.Accuracy.Balanced, which caused long time to get location sometimes. Android does not support Lowest. Although accuracy is low, it was accurate enough, and able to get location much faster than before.

https://forums.expo.io/t/location-getcurrentpositionasync-takes-10-seconds/19714/3

tenondecrpc avatar Oct 28 '20 17:10 tenondecrpc

@tenondecrpc I need to show user position on the map, I need more precision. I will test it again

rvieceli avatar Nov 16 '20 09:11 rvieceli

@rvieceli I tried passing it balanced as value, and even that value worked for me, a higher value gave problems. This is my code now, including the request for permission to the user:

// Get permissions const { status } = await Permissions.getAsync(Permissions.LOCATION); if (status !== 'granted') { return; }

// Get location
const location = await Location.getCurrentPositionAsync({ accuracy: Location.Accuracy.Balanced, });

tenondecrpc avatar Nov 16 '20 23:11 tenondecrpc

I am facing the same issue. Every time it takes more than 10 seconds in iOS to get location data. To prove the theory, I changed my library to @react-native-community/geolocation to get location and everything remains as it is. With @react-native-community/geolocation, I get response within a second. I am using expo-location 9.0.1

sharadrb avatar Nov 18 '20 06:11 sharadrb

We're getting the same issue since upgrading to 39. Our app has gotten very slow at getting a response back from this call.

fender avatar Nov 27 '20 14:11 fender

I followed the steps in the documentation as well as the lines stated above, but I still am stuck at "Waiting" for the location, never receiving the value

maralihart avatar Dec 16 '20 18:12 maralihart

Using this example https://docs.expo.io/versions/latest/sdk/location/#usage from documentation I created this snack https://snack.expo.io/@rvieceli/expo-issue-10756

I only added time result below the location result.

Android takes ~0.051 seconds to get my location iOS takes ~10.013 seconds to do same job.

rvieceli avatar Dec 28 '20 23:12 rvieceli

I also tested different SDK versions.

Using Precise Location as ON SDK37 -> 0.025 seconds SDK38 -> 0.035 seconds SDK39 -> 10.012 seconds SDK40 -> 10.013 seconds

Using Precise Location as OFF SDK37 -> 10.02 seconds SDK38 -> 10.015 seconds SDK39 -> 10.016 seconds SDK40 -> 10.022 seconds

rvieceli avatar Dec 29 '20 11:12 rvieceli

are there any updates?

guydani avatar Jan 05 '21 10:01 guydani

For me, I just forgot to turn on the emulator's location, but no problem

maralihart avatar Jan 05 '21 15:01 maralihart

Hey @maralihart, awesome!

My problem is also in production with standalone app.

Can you share with us our permissions, dependencies (only from expo) and your implementation if is different from expo documentation?

Thank you. have a nice day!

rvieceli avatar Jan 05 '21 15:01 rvieceli

Getting location was working fine for me on sdk 36 but upgrading to sdk 40 slowed it down to 10+ seconds. Any word from Expo on fixing this bug?

migueladelgado avatar Jan 13 '21 14:01 migueladelgado

I am also experiencing this problem. Is there an update please?

callum-katene avatar Jan 19 '21 07:01 callum-katene

I am using SDK39, and having the same issue. any solution, plz?

kyleyu714 avatar Jan 27 '21 05:01 kyleyu714

I am using SDK 40, In my case speed is a bit faster but anyway is not really acceptable: 4-6 seconds.

dennisbouwpas avatar Feb 02 '21 20:02 dennisbouwpas

So it seems that this is not a bug, and the documentation mentions this (https://docs.expo.io/versions/latest/sdk/location/).. What I ended up doing is using getLastKnownPositionAsync(), which is fast, to get the map started and then running getCurrentPositionAsync() in the background to get the more accurate location. Not the most elegant solution, but helps out.

migueladelgado avatar Feb 02 '21 21:02 migueladelgado

@rvieceli I tried passing it balanced as value, and even that value worked for me, a higher value gave problems. This is my code now, including the request for permission to the user:

// Get permissions const { status } = await Permissions.getAsync(Permissions.LOCATION); if (status !== 'granted') { return; }

// Get location const location = await Location.getCurrentPositionAsync({ accuracy: Location.Accuracy.Balanced, });

FYI this did not fix the issue for me on iOS 14.4.2 with Expo Go 2.19.3 and SDK 41. Latency is still ~11-12 seconds per API call. (Note when permission is being requested, iOS shows me a live preview of my current location so clearly has it already resolved to some - seemingly fine - resolution).

getLastKnownPositionAsync() does work for me in low latency on with these versions. Thanks @migueladelgado

(Minor note that getLastKnownPositionAsync didn't seem to work with RNWeb so I ended up using const location = await (Constants.platform.web ? Location.getCurrentPositionAsync() : Location.getLastKnownPositionAsync());)

owencm avatar Apr 24 '21 05:04 owencm

Live preview when IOS request permission is not under expo control. But you can have the same faster resolve using react-native-maps (showing user position).

rvieceli avatar Apr 25 '21 09:04 rvieceli

@rvieceli I tried passing it balanced as value, and even that value worked for me, a higher value gave problems. This is my code now, including the request for permission to the user:

// Get permissions const { status } = await Permissions.getAsync(Permissions.LOCATION); if (status !== 'granted') { return; }

// Get location const location = await Location.getCurrentPositionAsync({ accuracy: Location.Accuracy.Balanced, });

this sped it up for me but 100 meters is a bit problematic for my use case. does anyone know if this is an expo issue that could be avoided by ejecting to the the bare workflow and writing native iOS code? also considering downgrading the SDK to v38. thank you @rvieceli for doing the tests!

idodekerobo avatar Apr 27 '21 21:04 idodekerobo

Any update here? We have the same issue in the latest expo SDK and we would like to use a high accuracy.

Thanks for your help.

ruettenm avatar May 18 '21 23:05 ruettenm

Wanted to follow up here, any update? Same issue, looking for alternatives at the moment

Thanks friends

chrissabaitis avatar Jul 12 '21 18:07 chrissabaitis

Still experiencing this issue on v 42. I'll give the getLastKnownPositionAsync work around a shot.

bfreeman avatar Jul 30 '21 23:07 bfreeman

same sdk v42

melozzo avatar Aug 01 '21 13:08 melozzo

Location.installWebGeolocationPolyfill() await navigator.geolocation.getCurrentPosition(position => { const latitude = JSON.stringify(position.coords.latitude); const longitude = JSON.stringify(position.coords.longitude); reverseGeocode(position.coords); setCurrentLocation({ latitude, longitude }) return true; }, error => { console.log("error using navigator current position") }, { enableHighAccuracy: false, timeout: 2000, maxiumAge: 1000 })

this helps

melozzo avatar Aug 01 '21 14:08 melozzo

I am experiencing this as well. "Fixed" using lowest accuracy, but it would be good to be able to use high accuracy on ios

xaviserrag avatar Aug 06 '21 09:08 xaviserrag