expo: Location provider is unavailable. Make sure that location services are enabled.

Summary

We have what has been a stable application for months that requires location services. As of last week, we are seeing a massive influx of reports that location is not working, which breaks one of the primary functions of the application. This is not just a few people, but hundreds. We have two places in our application that requires location. It will work the first time, but not the second. Many times it will not work at all. Sometimes retrying 15-20 times allows it to work. This is causing serious issues for our business clients.

We are using SDK 40, as we are still vetting 41. I have seen reports of this happening to others even in SDK 42. https://github.com/expo/expo/issues/5504

There have been no changes to this application in months.

We were able to pull this log on a failed attempt:

{ "nativeStackAndroid":[ { "lineNumber":2, "file":"LocationModule.java", "methodName":"onLocationAvailability", "class":"expo.modules.location.LocationModule$1" }, { "lineNumber":4, "file":null, "methodName":"a", "class":"d.f.b.e.f.m.w" }, { "lineNumber":3, "file":"com.google.android.gms:play-services-base@@17.3.0", "methodName":"d", "class":"com.google.android.gms.common.api.internal.k" }, { "lineNumber":3, "file":"com.google.android.gms:play-services-base@@17.3.0", "methodName":"handleMessage", "class":"com.google.android.gms.common.api.internal.k$c" }, { "lineNumber":105, "file":"Handler.java", "methodName":"dispatchMessage", "class":"android.os.Handler" }, { "lineNumber":1, "file":"com.google.android.gms:play-services-base@@17.3.0", "methodName":"dispatchMessage", "class":"d.f.b.e.f.d.h" }, { "lineNumber":164, "file":"Looper.java", "methodName":"loop", "class":"android.os.Looper" }, { "lineNumber":8, "file":"MessageQueueThreadImpl.java", "methodName":"run", "class":"com.facebook.react.bridge.queue.MessageQueueThreadImpl$4" }, { "lineNumber":764, "file":"Thread.java", "methodName":"run", "class":"java.lang.Thread" } ], "userInfo":null, "message":"Location provider is unavailable. Make sure that location services are enabled.", "code":"E_LOCATION_UNAVAILABLE", "line":27, "column":1111, "sourceURL":"" }

Managed or bare workflow? If you have ios/ or android/ directories in your project, the answer is bare!

managed

What platform(s) does this occur on?

Android

SDK Version (managed workflow only)

40

Environment

Expo CLI 4.11.0 environment info: System: OS: Windows 10 10.0.22000 Binaries: Node: 14.17.0 - C:\Program Files\nodejs\node.EXE Yarn: 2.4.2 - C:\Program Files (x86)\Yarn\bin\yarn.CMD npm: 6.14.13 - C:\Program Files\nodejs\npm.CMD npmPackages: expo: ^40.0.0 => 40.0.0 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-40.0.1.tar.gz => 0.63.2 react-native-web: ~0.13.12 => 0.13.18 Expo Workflow: managed

Reproducible demo or steps to reproduce from a blank project

Create a project with proper permissions for fine location.

let location = await Location.getCurrentPositionAsync({ accuracy: LocationAccuracy.Low }); BestForNavigation, Highest, High all work. We have only tested this in our own source code.

This is how we have been able to readily reproduce it.

This throws the same exception for us ( in an Android emulator with the following setup:

  • Connected to wifi.

  • Location permission set as “Allow while using the app” in settings.

  • No location/ points saved in emulator.

Emulator details: Nexus6, Android API R x86

We cannot readily reproduce it in the production application, however nothing has changed since July 2021.

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 17
  • Comments: 50 (11 by maintainers)

Commits related to this issue

Most upvoted comments

Hi everyone,

I’m really sorry you’re encountering this issue on production apps — I can confirm it’s caused by an update to Google Play Services that we can’t really control. That’s a bit of a shame that Google is doing such things. Anyway, we will do our best to release this workaround to our builders. I intentionally don’t name it a fix, because we used the API correctly, according to the documentation.

Please give us some time to precisely test it before the release, we will keep you informed.

🔊 EDIT: See https://github.com/expo/expo/issues/14248#issuecomment-916181090 to track the progress

For everyone running into this issue locally with the Expo Go app, new binaries are deployed to production and will soon-ish be deployed to turtle. For now, you should be able to install the newer Expo Go versions using the EXPO_STAGING=1 environment variable.

Edit, the Expo Go binaries are available through the Expo CLI. Turtle has been updated with new shell apps as well. Create a new build with $ expo build:android to use the workaround.

Managed workflow

  • Go to your Expo project
  • $ expo client:install:android
  • Install recommended version

Here is a quick overview of the SDK and the Expo Go version you should be getting, and if it includes the workaround when building with $ expo build:android.

SDK Expo Go Turtle deployed?
42 2.21.6
41 2.19.7
40 2.18.8
39 2.17.6

Bare workflow (or EAS)

If you are using the bare workflow, make sure you installed expo-location@12.1.3, currently the next tag. This version includes the workaround. Note, this will be the only backported version we will send out through npm. Always update to the latest versions when using the bare workflow.

Alternatively, you can apply the patch from #14281 manually using patch-package. This also works in EAS.

Same with SDK41/managed, started erroring today morning, worked fine until then.

Some people reported that {accuracy: 6} or {Location.Accuracy.Low} or {Location.Accuracy.Lowest} worked for them. For us they did not, so we had to change getCurrentPositionAsync() to getLastKnownPositionAsync() everywhere.

It’s worth to note that some developers reported the issue starting a week ago others just now. Might be related to an android update?

Wait, what?! We didn’t have any possibility to check if your fixes work, and you closing this? I mean you could not possibly check it on all devices we listed (and I mean real devices)). SDK 42 is not even half a year old, so most applications still use 40/41. We are talking about production applications and paying expo money for build (so not about you working for free), at least in the case of the application I work on.

Here’s my workaround, it seems to be reliable and works for me. Expo sdk 41

//import * as geoLocation from 'expo-location';
//...

// const delay = ms => new Promise(res => setTimeout(res, ms));
//...

let locationCoords: geoLocation.LocationObject | null = null;

let getcurrentLocationReties = 0;
while (getcurrentLocationReties < 5) {
  try {
    locationCoords = await geoLocation.getCurrentPositionAsync({
      accuracy: geoLocation.Accuracy.BestForNavigation,
    });
    break;
  } catch {
    locationCoords = await geoLocation.getLastKnownPositionAsync({
      maxAge: 5000,
    });
    if (locationCoords == null) {
      getcurrentLocationReties++;
      await delay(1000);
    } else break;
  }
}

Also noticed that when calling getLastKnownPositionAsync (and returns null cuz maxAge = 5000) then waiting for a sec somehow manages to get getCurrentPositionAsync working fine on the second retry. Thus it always succeeds on the second loop. But just in case I set it up to 5.

Same thing here, no changes and all of sudden it stops working, but not for everyone and not all the time. Here’s how we get the location: none of accuracy settings work:

export const getPosition = async (): Promise<Location.LocationObject> => {
  if (!(await Location.hasServicesEnabledAsync())) {
    throw new Error('gps disabled');
  }

  const permission = await Location.requestPermissionsAsync();
  if (permission.status === 'granted') {
    /* eslint-disable-next-line */
    const promise1 = new Promise<LocationObject>(async resolve => {
      try {
        const res = await Location.getCurrentPositionAsync({ accuracy: Location.Accuracy.Highest });
        resolve(res);
      } catch (err) {
        //
      }
      try {
        const res = await Location.getCurrentPositionAsync({ accuracy: Location.Accuracy.Lowest });
        resolve(res);
      } catch (err) {
        //
      }
      try {
        const res = await Location.getCurrentPositionAsync({
          accuracy: Location.Accuracy.Balanced,
        });
        resolve(res);
      } catch (err) {
        //
      }
    });
    const promise2 = new Promise<'too-slow'>(resolve => {
      setTimeout(() => resolve('too-slow'), 6000);
    });

    // For whatever weird reason location methods somethings get totally stuck, never resolving. Wait for 6 seconds and deem failed if none of the methods have resolved at that point.
    const possibleLocation = await Promise.race<LocationObject | 'too-slow'>([promise1, promise2]);

    if (possibleLocation !== 'too-slow') {
      return possibleLocation;
    }
    // Everything failed
    const error = new Error('Unable to get location even if services are enabled');
    Sentry.Native.captureException(error);
    throw error;
  }
  throw new Error('permission denied');
};

SDK is 40

We are up to 103 users and climbing. It is no longer a trend of Samsung devices, but a whole bunch of different ones.

This problem is quite rare because if this is true I have tried with two phones with the same version of Google Play Services and in one of them it works but not in the other, so what is the reason? 🤔

Hi everyone, I’m really sorry you’re encountering this issue on production apps — I can confirm it’s caused by an update to Google Play Services that we can’t really control. That’s a bit of a shame that Google is doing such things. Anyway, we will do our best to release this workaround to our builders. I intentionally don’t name it a fix, because we used the API correctly, according to the documentation. Please give us some time to precisely test it before the release, we will keep you informed.

What are the devices, Android version, and full Google Play services version that you tested? I tested expo-location with and without the workaround on some of my old Android devices. For some Android versions, they use a slightly different version, even though the xx.yy.zz version is the same.

  • Nexus 5, Android 6.0.1, Google Play services 21.30.16 (040308-391784508)
    • works fine with and without the workaround
  • Nexus 5X, Android 8.1.0, Google Play services 21.30.16 (040400-391784508)
    • only works with the workaround
  • OnePlus 6, Android 10 (OxygenOS 10.3.12), Google Play services 21.30.58 (120400-392523775)
    • only works with the workaround

As @tsapeta said, it’s unfortunate that Google can break core services like the location provider, even on older Android versions. The location service is provided by them unless you use a customized Android distribution.

We will keep you posted when we finish the backport, testing, and rollout.

@lukmccall How can we work around this issue on current/older SDKs? Or are you saying that all Expo customers will no longer be able to use location services in their applications until the next SDK is released?

Thank you for the suggestion but trying for 50 times isn’t an ideal scenario for us and is more if a workaround than solution. Our clients are already disappointed in waiting for location locks before this happened. We have a smaller scale version of what you are doing here, just not that many tries, and we still get locks failing in places.

As for our own research, we found on one device that going back to Google Play Services 16.0.89 from July fixes the issues. Google Play Services plays a part in location acquisition on Google Play enabled devices, and Expo requires it from the logs I pulled from Android while trying on an AOSP device.

My working theory is that Google updated Play Services and broke something.

please help me …🙏🙏🙏🙏🙏🙏 for testing using – REdmi note 8 expo “expo”: “~39.0.2”, expo --version = WhatsApp Image 2021-09-03 at 2 36 39 PM 4.11.0

here is my code i tried everything… useEffect(() => { (async () => { try { if (Platform.OS === “android” && !Constants.isDevice) { setErrorMsg( “Oops, this will not work on Snack in an Android emulator. Try it on your device!” ); return; } let { status } = await Location.requestPermissionsAsync(); // let { status } = await Permissions.askAsync(Permissions.LOCATION); // Alert.alert(status); if (status !== “granted”) { setErrorMsg(“Permission to access location was denied”); return; } // let location = await Location.getCurrentPositionAsync({enableHighAccuracy: true}) console.log('longitude is ',)

			let location = await Location.getCurrentPositionAsync({})

			console.log('longitude is ', location)


			setLocation(location);
		} catch (error) {
			// if(Platform.OS==="android"){ location !== undefined
			if (count < 3) {
				setCount(count + 1);
			}
		}
	})();
	// }, []);
}, [count]);

showing – waiting…

only please help me into that

I think I’m missing something - we’re using the managed workflow and I’ve run the $ expo client:install:android command and it prompted me to install the correct client version (2.18.8 for SDK40) but after rebuilding this morning and submitting to our internal test track on the Play store I’m still seeing the location failure.

However, I’m still also seeing “Client version: 2.21.5” in my Expo Go app, which is why I assume I’m missing something. Any advice is appreciated!

Have you upgrade expo to 42.0.3? in the process reinstall explo-cli from emulator (also updates the expo go app from your device).

When i do this, location is back to my projects, also the signed builds, Don’t Forget that now await Location.requestPermissionsAsync(); is deprecated, use instead await Location.requestForegroundPermissionsAsync(); or background… hope it helps

Same here, I cant believe that there is no possibility to fix this with an update for SDK 40/41… I mean, we’re not talking about 2020 for SDK 41 for example…

Nokia 8 Sirocco (SDK 41) also has the same issue; no changes in code were made.

also on my Xiaomi Poco X3

This fails for me on my Pixel 3, so it seems to affect more than just Samsung.

Also on my LG

We are tracking devices that are having this issue. A large majority of them are from Samsung. That could be a trend, or that could just be that Samsung is a huge Android OEM.

This fails for me on my Pixel 3, so it seems to affect more than just Samsung.

Yes, we do have a Pixel 3 in our list too.

We are tracking devices that are having this issue. A large majority of them are from Samsung. That could be a trend, or that could just be that Samsung is a huge Android OEM.

This fails for me on my Pixel 3, so it seems to affect more than just Samsung.

We are tracking devices that are having this issue. A large majority of them are from Samsung. That could be a trend, or that could just be that Samsung is a huge Android OEM.