React Native Expo app crashing when published to Testflight
Asked Answered
D

2

7

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.

Denticulate answered 3/12, 2019 at 12:11 Comment(0)
D
9

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!

Denticulate answered 3/12, 2019 at 20:13 Comment(1)
This was pretty close to what happened for me too-- in my case, I wasn't even asking for the user's permission I was just calling a expo MapView without using the google maps API key.. worked great in expo go, testflight: no sir. Thank you!Agency
C
6

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

Chivaree answered 11/1, 2020 at 12:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.