expo-image-picker Crashes Android & IOS

Please provide the following:

  1. "expo": "^40.0.1"
  2. All
  3. expo-image-picker

On IOS when launching the image picker the App crashes.
On Android when choosing an image or cropping the image, the App crashes.

This bug only happens in a built version (via yarn build:staging).

I’m keeping a beady eye on this issue but at the moment this crashing issue is blocking my App as we upload images as part of the registration flow…

I thought getPendingResultAsync would help however the App crashes on IOS as well which makes me think there is a fundamental issue with either my setup or the Picker component.

Any help is greatly appreciated :slight_smile:

package.json

{
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "yarn configure:develop && expo start --clear",
    "start:staging": "yarn configure:staging && expo start --clear",
    "android": "yarn configure:develop && expo start --android",
    "ios": "yarn configure:develop && expo start --ios",
    "web": "yarn configure:develop && expo start --web",
    "eject": "expo eject",
    "test": "yarn configure:develop && jest --watchAll",
    "build:staging": "yarn configure:staging && eas build --profile staging --platform all",
    "build:staging:android": "yarn configure:staging && eas build --profile staging --platform android",
    "build:staging:ios": "yarn configure:staging && eas build --profile staging --platform ios",
    "register:ios": "eas device:create",
    "configure:develop": "node flavorConfig development",
    "configure:staging": "node flavorConfig staging && ./commitConfig.sh staging",
    "configure:production": "node flavorConfig production && ./commitConfig.sh production"
  },
  "jest": {
    "preset": "jest-expo"
  },
  "dependencies": {
    "@expo/vector-icons": "^12.0.0",
    "@expo/webpack-config": "~0.12.45",
    "@hookform/resolvers": "^1.3.4",
    "@react-native-async-storage/async-storage": "^1.13.4",
    "@react-native-community/datetimepicker": "3.0.4",
    "@react-native-community/masked-view": "0.1.10",
    "@react-navigation/bottom-tabs": "5.11.2",
    "@react-navigation/native": "~5.8.10",
    "@react-navigation/stack": "~5.12.8",
    "@reduxjs/toolkit": "^1.5.0",
    "@zealmatch/schema": "2.3.8",
    "axios": "^0.21.1",
    "axios-hooks": "^2.3.0",
    "date-fns": "^2.17.0",
    "dotenv": "^8.2.0",
    "expo": "^40.0.1",
    "expo-asset": "~8.2.1",
    "expo-checkbox": "~1.0.0",
    "expo-constants": "~9.3.3",
    "expo-firebase-analytics": "~2.6.0",
    "expo-font": "~8.4.0",
    "expo-image-picker": "~9.2.0",
    "expo-linear-gradient": "~8.4.0",
    "expo-linking": "~2.0.1",
    "expo-location": "~10.0.0",
    "expo-notifications": "~0.8.2",
    "expo-permissions": "~10.0.0",
    "expo-splash-screen": "~0.8.1",
    "expo-status-bar": "~1.0.3",
    "expo-web-browser": "~8.6.0",
    "firebase": "7.9.0",
    "fs": "^0.0.1-security",
    "geofirestore": "^4.4.1",
    "joi": "^17.3.0",
    "lodash.merge": "^4.6.2",
    "react": "16.13.1",
    "react-dom": "16.13.1",
    "react-hook-form": "^6.15.1",
    "react-native": "https://github.com/expo/react-native/archive/sdk-40.0.1.tar.gz",
    "react-native-elements": "^3.1.0",
    "react-native-gesture-handler": "~1.8.0",
    "react-native-get-random-values": "^1.6.0",
    "react-native-safe-area-context": "3.1.9",
    "react-native-screens": "~2.15.2",
    "react-native-shared-element": "0.7.0",
    "react-native-svg": "12.1.0",
    "react-native-toast-message": "^1.4.4",
    "react-native-web": "~0.13.12",
    "react-redux": "^7.2.2",
    "redux-persist": "^6.0.0",
    "text-encoding-polyfill": "^0.6.7",
    "uuid": "^8.3.2",
    "yup": "^0.32.9"
  },
  "devDependencies": {
    "@babel/core": "~7.9.0",
    "@types/react": "~16.9.35",
    "@types/react-native": "~0.63.2",
    "jest-expo": "^40.0.0",
    "typescript": "~4.0.0"
  },
  "private": true
}

app.json

{
  "expo": {
    "name": "App Staging",
    "slug": "App-Staging",
    "version": "1.0.0",
    "owner": "company",
    "orientation": "portrait",
    "icon": "./assets/images/icon.png",
    "scheme": "myapp",
    "userInterfaceStyle": "automatic",
    "splash": {
      "image": "./assets/images/splash.png",
      "resizeMode": "cover",
      "backgroundColor": "#74d693"
    },
    "updates": {
      "enabled": true,
      "fallbackToCacheTimeout": 0
    },
    "assetBundlePatterns": [
      "**/*"
    ],
    "ios": {
      "supportsTablet": false,
      "bundleIdentifier": "com.company.staging.App",
      "googleServicesFile": "./GoogleService-staging-Info.plist",
      "infoPlist": {
        "NSLocationWhenInUseUsageDescription": "Allow App to use your location",
        "UIBackgroundModes": [
          "location",
          "fetch"
        ]
      }
    },
    "android": {
      "adaptiveIcon": {
        "foregroundImage": "./assets/images/adaptive-icon.png",
        "backgroundColor": "#FFFFFF"
      },
      "package": "com.company.staging.App",
      "googleServicesFile": "./google-services-staging.json",
      "permissions": [
        "ACCESS_FINE_LOCATION",
        "CAMERA",
        "MEDIA_LIBRARY"
      ],
      "useNextNotificationsApi": true
    },
    "web": {...},
    "extra": {...}
  }
}

ImagePicker.tsx

import * as Picker from 'expo-image-picker';

...
React.useEffect(() => {
        (async () => {
          if (Platform.OS !== 'web') {
            const { status } = await Picker.requestMediaLibraryPermissionsAsync();
            if (status !== 'granted') {
              Toast.show({
                type: 'info',
                position: 'top',
                text1: '😨',
                text2: 'Sorry, we need access to your Images in order to complete your profile.',
            });
            }
          }
        })();
    }, []);

async function pickImage() {
        try {
            const result = await Picker.launchImageLibraryAsync({
                mediaTypes: Picker.MediaTypeOptions.Images,
                allowsEditing: true,
                aspect: [3, 5],
                quality: 0.5,
            });

            const androidResult = await Picker.getPendingResultAsync();

            const finalResult = androidResult.length ? androidResult[0] : result;

            if (!finalResult.cancelled) {
                setImage(result.uri);
                if (onSelect) {
                    onSelect(result.uri);
                }
            }
        } catch (error) {
            showImageUploadError();
        }
};
...

Hey @zealmatch, this is likely a result of trying to use eas build with a Managed project. We do not currently support managed eas builds. I would recommend continuing to use expo build until we add said support.

Cheers,
Adam

AHH right ok. That’s a shame as I’m paying for the service…

Do you know the pipeline for getting this functionality through? Just asking for steak holders as testing on iOS is easier with EAS build.

Did you end up going with expo build? I’m facing the same problem but if I go with expo build I don’t think I’ll be able to build for internal distribution because I’m not on a Mac.

I ended up building my own image-picker but now lack the ability to crop.

Really looking forward to when expo-image-picker works with eas-build

@adamjnav do you have a rough estimate of when EAS is going to handle managed builds? i remember seeing that the timeline for this work was due by the first quarter of 2021. :slight_smile:

The expo-image-picker now works on eas 'built versions after upgrading to Expo 41