Search code examples
iosreact-nativepermissionsexpolocation

React Native and Expo location on IOS not asking for permissions


I'm working on a React Native app built with Expo and am trying to get the location function to work. While testing it out using Expo Go, I am asked for permissions to use the location feature, but when I build it out an IOS build and test on testflight, I'm never asked for permission. I've tried looking in settings to add the permission, but location isn't even an option.

Where I ask for permission in the app

useEffect(() => {
        (async () => {
            let { status } = await Location.requestForegroundPermissionsAsync();
            if (status !== 'granted') {
                setErrorMsg('Permission to access location was denied');
                return;
            }
        }, []);
    }, []);

IOS section of app.json:

"ios": {
      "supportsTablet": true,
      "bundleIdentifier": "com.nawdevelopment.discgolfgames",
      "buildNumber": "1.0.4",
      "infoPlist":{
        "NSLocationUsageDescription":"Disc Golf Games uses location to determine distances, which is used for several games",
        "NSLocationWhenInUseUsageDescription":"Disc Golf Games uses location to determine distances, which is used for several games",
        "NSLocationAlwaysUsageDescription":"Disc Golf Games uses location to determine distances, which is used for several games",
        "NSLocationUsageDescription":"Disc Golf Games uses location to determine distances, which is used for several games",
        "UIBackgroundModes": [
          "location",          
        ]
      }
    },

package.json:

{
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios",
    "web": "expo start --web",
    "eject": "expo eject"
  },
  "dependencies": {
    "@react-native-community/masked-view": "^0.1.11",
    "@unimodules/core": "~7.2.0",
    "@unimodules/react-native-adapter": "~6.5.0",
    "ansi-regex": "^4.1.1",
    "expo": "^44.0.0",
    "expo-linear-gradient": "~11.0.3",
    "expo-location": "~14.0.1",
    "expo-permissions": "^13.2.0",
    "expo-status-bar": "~1.2.0",
    "expo-task-manager": "~10.1.0",
    "expo-updates": "~0.11.7",
    "minimist": "^1.2.6",
    "node-fetch": "^2.6.1",
    "plist": "^3.0.5",
    "react": "17.0.1",
    "react-dom": "17.0.1",
    "react-native": "0.64.3",
    "react-native-elements": "^3.4.1",
    "react-native-gesture-handler": "~2.1.0",
    "react-native-reanimated": "~2.3.1",
    "react-native-safe-area-context": "3.3.2",
    "react-native-screens": "~3.10.1",
    "react-native-web": "0.17.1",
    "react-navigation": "^4.4.4",
    "react-navigation-stack": "^2.10.4",
    "react-navigation-tabs": "^2.11.1",
    "unimodules-permissions-interface": "^6.1.0",
    "url-parse": "1.5.10"
  },
  "devDependencies": {
    "@babel/core": "^7.12.9"
  },
  "private": true
}

Solution

  • Looking at the anonymous function in your useEffect, it isn't called correctly.

    Anonymous functions need () after them to be called. Example:

    (function() {
        console.log('Hi!');
    })();
    

    Source: https://www.javascripttutorial.net/javascript-anonymous-functions/

    I took a look at Expo's docs as well and I believe what you are trying to accomplish in your useEffect is the following:

    useEffect(() => {
        (async () => {
          let { status } = await Location.requestForegroundPermissionsAsync();
          if (status !== 'granted') {
            setErrorMsg('Permission to access location was denied');
            return;
          }
        })();
      }, []); //You have this line twice instead and are missing the line above this one
    

    Source: https://docs.expo.dev/versions/v45.0.0/sdk/location/#usage

    Without the () your anonymous function in your useEffect isn't being called, which is probably why you're never asked for permission.

    As for your app.json and package.json, it looks like you have everything properly installed. What you should make sure is that in the "plugins" section of app.json you have expo-location showing up.