I have a react native Expo app that uses Location permissions. It works great on my device and on the Simulators so moving to the next step of distribution - TestFlight. When I load the ipa to Testflight and then try to run the app, the app works up to the point that I ask the User for Permission. (So the app loads, authentication works, links to my server and db are all working etc).
At the point where the code requests user location permission, the usual alert "Allow while using app, Allow always, don't Allow" flickers on the screen for a couple of milliseconds then the app crashes and I get the option to share comments to Testflight.
The code which asks for permission is here:
import * as Location from 'expo-location';
import * as Permissions from 'expo-permissions';
import createDataContext from '../../Context/createDataContext';
const deviceLocationReducer = (state, action) => {
switch (action.type) {
case 'get_device_location':
return action.payload;
default:
return state;
}
};
const getDeviceLocation = dispatch => async () => {
let deviceLocation = null;
try {
// Ask User permission for location
const { status } = await Permissions.askAsync(Permissions.LOCATION);
console.log('\n***\nDeviceLocationContext.js: Permission status', status);
if (status === 'granted') {
// Permission granted, get user location
deviceLocation = await Location.getCurrentPositionAsync({});
console.log('DeviceLocationContext.js: Setting Context', deviceLocation);
} else {
console.log(
'DeviceLocationContext.js: Permission to access location denied'
);
}
dispatch({
type: 'get_device_location',
payload: deviceLocation,
});
} catch ({ message }) {
console.log(
`DeviceLocationContext.js: Get Device Location Error: ${message}`
);
}
};
export const { Context, Provider } = createDataContext(
deviceLocationReducer,
{ getDeviceLocation },
null
);
app.json here
{
"expo": {
"name": "MyApp",
"description": "MyApp Description",
"slug": "client",
"privacy": "public",
"sdkVersion": "35.0.0",
"platforms": ["ios", "android"],
"version": "0.0.7",
"orientation": "portrait",
"icon": "./assets/images/icon.png",
"splash": {
"image": "./assets/images/splash.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"updates": {
"fallbackToCacheTimeout": 0
},
"assetBundlePatterns": ["**/*"],
"ios": {
"supportsTablet": true,
"bundleIdentifier": "com.reachout.myapp",
"icon": "./assets/images/icon.png",
"infoPlist": {
"NSCameraUsageDescription": "Please allow access to add your photo.",
"NSPhotoLibraryUsageDescription": "Please allow access to select an image from your photo library.",
"NSLocationWhenInUseUsageDescription": "Please allow access to show venues near you"
},
"buildNumber": "0.0.7"
},
"android": {
"permissions": [
"CAMERA",
"ACCESS_COARSE_LOCATION",
"ACCESS_FINE_LOCATION"
],
"versionCode": 7,
"icon": "./assets/images/icon.png"
}
}
}
package.json here
{
"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": {
"@expo/vector-icons": "^10.0.6",
"axios": "^0.19.0",
"expo": "^35.0.0",
"expo-camera": "^7.0.0",
"expo-constants": "~7.0.0",
"expo-font": "^7.0.0",
"expo-image-picker": "~7.0.0",
"expo-location": "~7.0.0",
"expo-permissions": "^7.0.0",
"lodash": "^4.17.15",
"react": "16.8.3",
"react-dom": "16.8.3",
"react-native": "https://github.com/expo/react-native/archive/sdk-35.0.0.tar.gz",
"react-native-elements": "^1.2.7",
"react-native-gesture-handler": "^1.3.0",
"react-native-image-picker": "^1.1.0",
"react-native-map-clustering": "^3.0.6",
"react-native-maps": "^0.26.1",
"react-native-paper": "^3.1.1",
"react-native-ratings": "^6.5.0",
"react-native-reanimated": "^1.2.0",
"react-native-web": "^0.11.7",
"react-navigation": "^4.0.10",
"react-navigation-stack": "^1.9.4",
"react-navigation-tabs": "^2.5.6"
},
"devDependencies": {
"babel-eslint": "^9.0.0",
"babel-preset-expo": "^7.0.0",
"eslint": "^5.16.0",
"eslint-config-airbnb": "^17.1.1",
"eslint-config-prettier": "^4.3.0",
"eslint-config-wesbos": "0.0.19",
"eslint-plugin-html": "^5.0.5",
"eslint-plugin-import": "^2.18.2",
"eslint-plugin-jsx-a11y": "^6.2.3",
"eslint-plugin-prettier": "^3.1.1",
"eslint-plugin-react": "^7.16.0",
"eslint-plugin-react-hooks": "^1.7.0",
"prettier": "^1.19.1"
},
"private": true
}
Does anyone have any ideas? I'm drawing a total blank - I have run the build from expo in both production and dev, I have cleared expo caches, I have deleted the app from my device and loaded again - all to no avail.
So I have a 'working' app which I cant distribute for testing. Help!!
Also - I have no idea how to debug or access the crash data on Testflight for an expo built app - again - any help greatly appreciated. Thanks.
Select 'My Apps' and you should see your app listed. Click 'TestFlight' from the menu bar at the top. This will show your current app builds that are available for testing. In order to test the app on your device, you will need to install the TestFlight iOS app from the App Store, and sign in using your Apple ID.
Here are some good reasons to use Expo to build your React Native app. If you are given a project that needs rapid development, and you have picked React Native to build the cross-platform app, Expo is the best fit for you. With Expo, you can build and deploy React Native apps for both iOS and Android with ease.
It is better to use Expo CLI if you are new to app development. Expo CLI is a safe choice for a new React Native programmer. It has a list of tools built around React Native. That's why you only need to download a recent version of Node.
Solved :) - will leave here just in case anyone else has this kind of issue as this one had me stuck for several days and builds.
My problem was that I was asking for user location in a useEffect hook from a component that also mounted a Mapview. In the Mapview I had set my provider
prop to google
.
If you do this then you must add a gogleMapApi key in your info plist. To be fair to Expo it actually does state this in the MapView documentation but it is right down at the bottom as an aside after the Android documentation. I realised my problem and the solution from this thread after trawling through my logs for hours and finding that the problem was a google api error, NOT a permission location one.
[https://forums.expo.io/t/how-to-set-googlemaps-with-gmsservices-provideapikey/17770][1]
Hope this helps someone!
I also faced the problem of not being able to identify the JS error and I wanted to share how one can debug this.
For iOS, you can build the standalone app with a simulator option and the crash logs are stored here:
~/Library/Logs/DiagnosticReports/
I've written more details on this here.
https://medium.com/@tak215/expo-rash-on-standalone-app-only-how-to-debug-29c88c69c821?sk=babf382671e1c8c5bf97a74773d4f4f5
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With