Search code examples
javascriptreact-nativepermissionsbackgroundexpo

Expo Background Permissions Async is not working


I am developing an app where my users will sometimes need to be tracked as they are outside of the app. I have gone through the expo docs and it appears I am supposed to work with Foreground and Background Permissions Async functions but my expo app does not recognize either version. Has anyone else encountered this? How do I fix this? Below is some of my code:

import * as  Permissions from 'expo-permissions'; 
import * as Request from 'expo-permissions';
import * as Location from 'expo-location';
import Constants from 'expo-constants'


useEffect(() => {
    (async () => {
      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.requestForegroundPermissionsAsync();
      if (status !== 'granted') {
        setErrorMsg('Permission to access location was denied');
        return;
      }
      let location = await Location.getCurrentPositionAsync({});
      setLocation(location);
    })();
  }, []);

  useEffect (() =>{
    (async () => {
      if (Platform.OS === 'android' && !Constants.isDevice){
        setErrorMsg2(
          'Whoops'
        );
        return;
      }
      let { status2 } = await Location.requestBackgroundPermissionsAsync();
      if (status2 !== 'granted') {
        setErrorMsg2('Permission to access background location was denied');
        return;
      }
      let location2 = await Location.getCurrentPositionAsync({})
      setLocation2(location2)
    })()
  },[])

  let text = 'Waiting..';
  if (errorMsg) {
    text = errorMsg;
  }
   else if (location) {
    text = JSON.stringify(location);
  }

  let text2 = 'Also Wating...';
    if (errorMsg2){
      text2 = errorMsg2;
    }
    else if (location) {
      text2 = JSON.stringify(location)
    }

I am running Expo in managed workflow, currently using Expo version 3.23.2, but have also tested it on version 4.3.2, and have been thrown the same errors.


Solution

  • While using expo-location, you have to keep these points in mind :

    1. Location.requestBackgroundPermissionsAsync() Asks the user to grant permissions for location while the app is in the background. On Android 11 or higher: this method will open the system settings page - before that happens you should explain to the user why your application needs background location permission.

    2. Foreground permissions should be granted before asking for the background permissions (your app can't obtain background permission without foreground permission).

    Refer to the docs here

    Note : This has been tested on SDK 41 and expo-location's version 12.2.1

    Working Example for Background Location here

    How I've implemented it

    import { useState, useEffect } from "react";
    import { Text, View, StyleSheet } from "react-native";
    import * as Location from "expo-location";
    
    export default function App() {
      const [location, setLocation] = useState(null);
      const [errorMsg, setErrorMsg] = useState(null);
    
      useEffect(() => {
        (async () => {
          let { status } = await Location.requestForegroundPermissionsAsync();
          if (status !== "granted") {
            setErrorMsg("Permission to access location was denied");
            return;
          }
    
          let location = await Location.getCurrentPositionAsync({});
          setLocation(location);
    
          let backPerm = await Location.requestBackgroundPermissionsAsync();
          console.log(backPerm);
        })();
      }, []);
    
      let text = "Waiting..";
      if (errorMsg) {
        text = errorMsg;
      } else if (location) {
        text = JSON.stringify(location);
      }
    
      return (
        <View style={styles.container}>
          <Text style={styles.paragraph}>{text}</Text>
        </View>
      );
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        justifyContent: "center",
        paddingTop: 50,
        backgroundColor: "#ecf0f1",
        padding: 8,
      },
      paragraph: {
        margin: 24,
        fontSize: 18,
        fontWeight: "bold",
        textAlign: "center",
      },
    });
    

    First, it asks me the foreground Permission, I tapped on While Using the app

    Foregorund Permission Prompt

    Then, for background location permission it takes me to the device settings page to allow location access in the background

    Background Location Permission Settings Page

    If by any chance this doesn't work as expected, try these steps

    1. Clear all the permission given to Expo Go app.
    2. Clear Cache and app data
    3. Uninstall and restart your device, and then again download Expo go app