expo: Expo image picker always include camera permission even if I don't need it

Summary

I’m using eas build to build and then submit the apk to Play Store but I noticed a message: Your APK or Android App Bundle is using permissions that require a privacy policy: (android.permission.CAMERA). .

When I check expo config --type introspect here’s the result:

{
    android: {
    versionCode: 2,
    permissions: [
      'android.permission.ACCESS_COARSE_LOCATION',
      'android.permission.ACCESS_FINE_LOCATION',
      'android.permission.CAMERA',
      'android.permission.READ_EXTERNAL_STORAGE',
      'android.permission.WRITE_EXTERNAL_STORAGE',
      'android.permission.RECORD_AUDIO',
      'android.permission.INTERNET',
      'android.permission.FOREGROUND_SERVICE'
    ],
    adaptiveIcon: {
      foregroundImage: './assets/adaptive-icon.png',
      backgroundColor: '#111828'
    }
  },
}

Even if my app only using a camera roll access, expo-image-picker will always set a permission for camera and record audio which I don’t need

I tried to patch the package using patch-packages and set a "eas-build-post-install": "patch-package" on my package.json. I saw the post-install script is running but the .aab output will still have the same permissions.

I think expo-image-picker should have a config for us to set a permission based on our needs. Thanks!

Managed or bare workflow? If you have ios/ or android/ directories in your project, the answer is bare!

managed

What platform(s) does this occur on?

Android

SDK Version (managed workflow only)

42

Environment

Expo CLI 4.10.1 environment info: System: OS: macOS 11.5 Shell: 3.1.2 - /usr/local/bin/fish Binaries: Node: 14.10.1 - ~/.asdf/installs/nodejs/14.10.1/bin/node Yarn: 1.22.10 - /usr/local/bin/yarn npm: 6.14.8 - ~/.asdf/installs/nodejs/14.10.1/bin/npm Watchman: 2021.09.06.00 - /usr/local/bin/watchman Managers: CocoaPods: 1.9.3 - /Users/rikoriswandha/.rbenv/shims/pod SDKs: iOS SDK: Platforms: iOS 14.5, DriverKit 20.4, macOS 11.3, tvOS 14.5, watchOS 7.4 IDEs: Android Studio: 3.6 AI-192.7142.36.36.6392135 Xcode: 12.5.1/12E507 - /usr/bin/xcodebuild npmPackages: expo: ~41.0.0 => 41.0.1 react: 16.13.1 => 16.13.1 react-dom: 16.13.1 => 16.13.1 react-native: https://github.com/expo/react-native/archive/sdk-41.0.0.tar.gz => 0.63.2 react-native-web: ~0.13.12 => 0.13.18 npmGlobalPackages: expo-cli: 4.10.1 Expo Workflow: managed

Reproducible demo or steps to reproduce from a blank project

  1. Run expo init
  2. Install image picker expo install expo-image-picker
  3. Run eas build --platform all

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 9
  • Comments: 18 (11 by maintainers)

Most upvoted comments

@rikoriswandha I was about to do the exact same thing, thanks a lot for confirming it’s working !

EDIT: I also had to remove these permissions in expo-image-picker/android/src/main/AndroidManifest.xml

Also, for yarn v2/v3 users like me, no need of patch-package (it’s not supported), instead :

yarn patch expo-image-picker
# follow instructions, patch these files in the temp directory shown
# android/src/main/AndroidManifest.xml
# plugin/build/withImagePicker.js
# plugin/src/withImagePicker.ts

yarn patch-commit -s <temp-directory-displayed>

This set a new resolution in package.json with the patch referenced.

Important: ensure the resolution version exactly match the semver reference in the dependencies, ie you have "expo-image-picker": "~11.0.3" in dependencies, use also the ~ in resolution :

"resolutions": {
  "expo-image-picker@~11.0.3": "patch:expo-image-picker....."
}

No need for post install script because yarn automatically apply the patch at installation (but the semver must match)

Source: https://github.com/ds300/patch-package/issues/272#issuecomment-944877317

@rikoriswandha great finding! @byCedric actually issue is bigger. It also add the android.permission.RECORD_AUDIO permission even though we dont need it. In most europe because of GDPR there is a heightened awareness and averision not to install an app if it as RECORD_AUDIO permissions => bad. Also imagine the discussion between developer and stakeholder. StakeHolder: Why does google say that we need to record audio. We are building a simple image picker app. Developer: We are using expo-image-picker which requires RECORD_AUDIO on android platform. Stakeholder: Why are we using expo again ? 😃 lol

This issue still there and it’s kind of important. I’m getting this warning on Google Play Console, and probably because of this.

Screen Shot 2022-03-04 at 01 33 08

While my permissions for Android, in app.json are:

      "permissions": [
        "ACCESS_COARSE_LOCATION",
        "ACCESS_FINE_LOCATION",
        "READ_EXTERNAL_STORAGE",
        "WRITE_EXTERNAL_STORAGE"
      ],

And my code:

Screen Shot 2022-03-04 at 01 34 29

The issue is still present @github-actions 😉

@colinux @anback my temporary workaround is by installing patch-package and patch the expo-image-picker permission inside your node_modules. Here’s the step:

  1. npm install patch-package or yarn add patch-package postinstall-postinstall if you’re using yarn. Refer to https://github.com/ds300/patch-package
  2. Open node_modules/expo-image-picker/plugin/build/withImagePicker.js and delete permissions that you don’t need inside the withImagePicker function
  3. Run npx patch-package expo-image-picker or yarn patch-package expo-image-picker
  4. Add a script inside your package.json for patching after build. I’m using eas-build so in my case the script is: "eas-build-post-install": "patch-package"
  5. Run locally or rebuild your app and resubmit to Play Store

Here’s my edited withImagePicker.js for reference

const withImagePicker = (config, { photosPermission, cameraPermission, microphonePermission } = {}) => {
    if (!config.ios)
        config.ios = {};
    if (!config.ios.infoPlist)
        config.ios.infoPlist = {};
    config.ios.infoPlist.NSPhotoLibraryUsageDescription =
        photosPermission || config.ios.infoPlist.NSPhotoLibraryUsageDescription || READ_PHOTOS_USAGE;
    return config_plugins_1.withPlugins(config, [
        [
            config_plugins_1.AndroidConfig.Permissions.withPermissions,
            [
                'android.permission.READ_EXTERNAL_STORAGE',
                'android.permission.WRITE_EXTERNAL_STORAGE',
            ],
        ],
        withImagePickerManifestActivity,
    ]);
};