expo
expo copied to clipboard
Location.getCurrentPositionAsync() sometimes never responds or takes a very long time to respond
🐛 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
Hey @rvieceli, you mention this occurred after upgrading...have you been able to reproduce this with a newly created SDK39 project as well?
@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.
@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.
@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.
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.
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 I need to show user position on the map, I need more precision. I will test it again
@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, });
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
We're getting the same issue since upgrading to 39. Our app has gotten very slow at getting a response back from this call.
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
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.
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
are there any updates?
For me, I just forgot to turn on the emulator's location, but no problem
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!
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?
I am also experiencing this problem. Is there an update please?
I am using SDK39, and having the same issue. any solution, plz?
I am using SDK 40, In my case speed is a bit faster but anyway is not really acceptable: 4-6 seconds.
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.
@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());
)
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 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!
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.
Wanted to follow up here, any update? Same issue, looking for alternatives at the moment
Thanks friends
Still experiencing this issue on v 42. I'll give the getLastKnownPositionAsync work around a shot.
same sdk v42
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
I am experiencing this as well. "Fixed" using lowest accuracy, but it would be good to be able to use high accuracy on ios