Search code examples
react-nativelocationexpo

Expo Location Error: Unhandled promise rejection: Error: Not authorized to use background location services


I want to get the user's location even when the App is in the background. I am using expo-location and expo-task-manager in the following manner:

import * as React from "react";
import {
  StyleSheet,
  StatusBar,
  Platform,
  SafeAreaView,
  TouchableOpacity,
  Text,
} from "react-native";
import * as TaskManager from "expo-task-manager";
import * as Location from "expo-location";

const STATUSBAR_HEIGHT = Platform.OS === "os" ? 20 : StatusBar.currentHeight;
const LOCATION_TASK_NAME = "background-location-task";

export default function TestingGround({ navigation }) {
  const onPress = async () => {
    const { status } = await Location.requestPermissionsAsync();
    if (status === "granted") {
      await Location.startLocationUpdatesAsync(LOCATION_TASK_NAME, {
        accuracy: Location.Accuracy.Highest,
      });
    }
  };
  return (
    <SafeAreaView style={styles.container}>
      <TouchableOpacity
        style={{
          height: 50,
          width: 300,
          backgroundColor: "red",
          justifyContent: "center",
          alignItems: "center",
        }}
        onPress={onPress}
      >
        <Text>Enable background location</Text>
      </TouchableOpacity>
    </SafeAreaView>
  );
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "white",
    paddingTop: STATUSBAR_HEIGHT,
    justifyContent: "center",
    alignItems: "center",
  },
});

TaskManager.defineTask(LOCATION_TASK_NAME, ({ data, error }) => {
  if (error) {
    // Error occurred - check `error.message` for more details.
    console.log("error", error);
    return;
  }
  if (data) {
    const { locations } = data;
    // do something with the locations captured in the background
    console.log("locations", locations);
  }
});

On press, I get the error: Unhandled promise rejection: Error: Not authorized to use background location services. Location services are enabled. I don't understand what I need to do.

I also added the following to my App.json but with no success:

 "android": {
     ...
      "permissions": [
        "CAMERA",
        "ACCESS_FINE_LOCATION",
        "ACCESS_BACKGROUND_LOCATION"]
    },
    "ios": {
      "supportsTablet": true,
      "infoPlist": {
        "UIBackgroundModes": [
          "location",
          "fetch"
        ]
      }
    }


Solution

  • Well after a week of battling it I finally found a solution. It turns out that the reason I am getting this error is simply because I am running this code on Expo which does not allow background location fetching. There is nothing wrong with the code, all I had to do was to build a standalone App (expo build:android) and the standalone version of the App worked just fine and could fetch background location 😁

    I also passed an extra parameter to my Location.startLocationUpdatesAsync which increased the effectiveness of background-location fetching and actually allowed me to visualize that the App is fetching the background-location via a notification like this:

    const onPress = async () => {
      const { status } = await Location.requestPermissionsAsync();
      if (status === "granted") {
        await Location.startLocationUpdatesAsync(LOCATION_TASK_NAME, {
          accuracy: Location.Accuracy.BestForNavigation,
          timeInterval: 3000,
          foregroundService: {
            notificationTitle: "BackgroundLocation Is On",
            notificationBody: "We are tracking your location",
            notificationColor: "#ffce52",
          },
        });
      }
    };

    I hope this helps someone out there and don't hesitate to contact me for further assistance on this matter.