expo / expo

An open-source framework for making universal native apps with React. Expo runs on Android, iOS, and the web.
https://docs.expo.dev
MIT License
34.26k stars 5.47k forks source link

[expo-media-library] getAssetsAsync causes the app to crash in Android (Expo Client and Standalone) #10848

Closed charliegmv closed 3 years ago

charliegmv commented 4 years ago

🐛 Bug Report

Summary of Issue

Calling MediaLibrary.getAssetsAsync crashes the app on both Expo Client and standalone. There is no error logged and no indication of what could be causing the issue. This only happens in Android devices, works fine for iOS.

Environment - output of expo diagnostics & the platform(s) you're targeting

  Expo CLI 3.28.2 environment info:
    System:
      OS: Linux 5.9 Manjaro Linux
      Shell: 5.0.18 - /bin/bash
    Binaries:
      Node: 12.18.1 - ~/.config/nvm/versions/node/v12.18.1/bin/node
      Yarn: 1.22.4 - ~/.config/nvm/versions/node/v12.18.1/bin/yarn
      npm: 6.14.5 - ~/.config/nvm/versions/node/v12.18.1/bin/npm
    npmGlobalPackages:
      expo-cli: 3.28.2
    Expo Workflow: managed

Expo SDK: 39
expo-media-library: 9.2.1

And the standalone app is running on a Pixel 4 with Android 11 (although this issue has been happening since Android 10).

Reproducible Demo

I created this snack with the code I'm currently using, however I cannot reproduce the same error in the snack for some reason.

Steps to Reproduce

        const params = {
            first: 59,
            mediaType: [
                MediaLibrary.MediaType.photo,
                MediaLibrary.MediaType.video,
            ],
            sortBy: [MediaLibrary.SortBy.modificationTime],
        };

        if (lastItemId) {
            params.after = lastItemId;
        }

        try {
            const library = await MediaLibrary.getAssetsAsync(params);

            if (library.totalCount) {
                if (lastItemId !== library.endCursor) {
                    setGallery([...gallery, ...library.assets]);
                    setLastItemId(library.endCursor);
                }
            }
        } catch(e) {
            Alert.alert(
                'Gallery failed', 'An error happened fetching the gallery'
            );

            Logger.error('Error fetching gallery', e);
        }

Nothing after const library = await MediaLibrary.getAssetsAsync(params) gets executed and the app suddenly crashes.

Expected Behavior vs Actual Behavior

This is similar to some previous issues that are currently closed (#9440, #10168, #10488) and this is still happening in SDK 39. I have tested this same code in a physical iPhone and an iPhone simulator, with and without images to load, and has never crashed. I'm not sure if it is the same bug from the above mentioned tickets that is still persisting in SDK 39 or if this is a new one.

brentvatne commented 4 years ago

hello! please share a proper reproducible example: https://stackoverflow.com/help/mcve

the main thing here is we should be able to copy and paste it into an app and run it without any changes, or clone a repository and run it, or run it directly in snack

charliegmv commented 4 years ago

Ok, created a snack with my code but cannot make it crash there. Also, if I run the code in a different laptop I get it working fine, without any error. This is the expo diagnostics from the MacBook that made the code work:

  Expo CLI 3.27.12 environment info:
    System:
      OS: macOS 10.15.7
      Shell: 5.7.1 - /bin/zsh
    Binaries:
      Node: 12.18.2 - ~/.nvm/versions/node/v12.18.2/bin/node
      npm: 6.14.5 - ~/.nvm/versions/node/v12.18.2/bin/npm
    SDKs:
      iOS SDK:
        Platforms: iOS 13.5, DriverKit 19.0, macOS 10.15, tvOS 13.4, watchOS 6.2
    IDEs:
      Android Studio: 4.0 AI-193.6911.18.40.6626763
      Xcode: 11.5/11E608c - /usr/bin/xcodebuild
    npmPackages:
      expo: ^39.0.0 => 39.0.3 
      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-39.0.3.tar.gz => 0.63.2 
      react-native-web: ~0.13.7 => 0.13.14 
      react-navigation: ^4.3.7 => 4.4.2 
    npmGlobalPackages:
      expo-cli: 3.27.12
    Expo Workflow: managed
byCedric commented 4 years ago

Hi @charliegmv, what's the version of the Expo Client you are using? It could be related to outdated native code, so that would be good if you can provide that 😄

charliegmv commented 4 years ago

@byCedric Expo Client v2.17.5

davidbaskin33 commented 4 years ago

@brentvatne @byCedric Is there any more information that we can provide?

brentvatne commented 4 years ago

@davidbaskin33 - yes, as i requested above:

hello! please share a proper reproducible example: https://stackoverflow.com/help/mcve

the main thing here is we should be able to copy and paste it into an app and run it without any changes, or clone a repository and run it, or run it directly in snack

@charliegmv was unable to create a reproducible example, so we need this still

davidbaskin33 commented 4 years ago

@brentvatne thanks for the prompt reply. This issue is specifically reproducible on a Pixel 4 device, and we confirmed today that the snack also reproduces the issue on a Pixel 4. Do you have any suggestions for moving forward with this given that data point?

brentvatne commented 4 years ago

@davidbaskin33 - what android version on your pixel 4?

brentvatne commented 4 years ago

also, shoutout to carole

davidbaskin33 commented 4 years ago

@brentvatne Aunt Carole says hello! and Android 11

brentvatne commented 4 years ago

Screen Shot 2020-11-03 at 3 50 16 PM

running the snack on pixel 4 android 11 emulator. works as expected. can you record a video of this happening? and can you run adb logcat with your device connected, then make the crash happen, and then share the entire contents of the logs that were output during that time?

sbardian commented 4 years ago

I am crashing without error as soon as MediaLibrary.getAssetsAsync or MediaLibrary.getAlbumsAsync are called. Permissions have been confirmed to be granted.

Phone: OnePlus 8 model: IN2017 Android 10

Expo diagnostics: Expo CLI 3.27.7 environment info: System: OS: macOS 10.15.7 Shell: 5.7.1 - /bin/zsh Binaries: Node: 12.13.1 - ~/.nvm/versions/node/v12.13.1/bin/node Yarn: 1.22.5 - /usr/local/bin/yarn npm: 6.12.1 - ~/.nvm/versions/node/v12.13.1/bin/npm Watchman: 4.9.0 - /usr/local/bin/watchman SDKs: iOS SDK: Platforms: iOS 13.4, DriverKit 19.0, macOS 10.15, tvOS 13.4, watchOS 6.2 IDEs: Xcode: 11.4.1/11E503a - /usr/bin/xcodebuild Expo Workflow: managed

maxipetrucci commented 3 years ago

Upgrade to SDK39 and MediaLibrary 9.2.1 (automatically if you upgrade via expo's upgrade command) solves the problem.

charliegmv commented 3 years ago

Upgrade to SDK39 and MediaLibrary 9.2.1 (automatically if you upgrade via expo's upgrade command) solves the problem.

@maxipetrucci We are using both SDK39 and MediaLibrary 9.2.1 and the crash is still happening.

  Expo CLI 3.28.2 environment info:
    System:
      OS: Linux 5.9 Manjaro Linux
      Shell: 5.0.18 - /bin/bash
    Binaries:
      Node: 12.18.1 - ~/.config/nvm/versions/node/v12.18.1/bin/node
      Yarn: 1.22.4 - ~/.config/nvm/versions/node/v12.18.1/bin/yarn
      npm: 6.14.5 - ~/.config/nvm/versions/node/v12.18.1/bin/npm
    npmGlobalPackages:
      expo-cli: 3.28.2
    Expo Workflow: managed

Expo SDK: 39
expo-media-library: 9.2.1
charliegmv commented 3 years ago

Still haven't been able to get the logs from adb logcat, but we were able to record a video of the issue. Here's the video. A modal with the gallery should pop up after tapping the Image button, but instead the app just crashes.

davidbaskin33 commented 3 years ago

@charliegmv and I worked together today quite a bit with a user who can reproduce the issue (we now have reports from multiple users). Unfortunately, we aren’t able to reproduce it ourselves yet, so we haven’t been able to get the adb logcat log.

Charlie made a build that loaded the Gallery incrementally, and we were able to pinpoint a “photo” that we believe is causing this issue on the user’s device when loaded via MediaLibrary.getAssetsAsync. The file appears to be a 0 byte file with no content that the user was not able to share or copy to an SD card (we haven’t tried deleting it because this is our best way to reproduce the issue, but all operations we have tried so far have failed). She was only able to provide the following 2 screenshots of the photo on her device.

We also found that the crash only occurred when two conditions are both true:

  1. We call with options.first > 1. With options.first = 1, we get an exception instead of the app crashing
  2. We call with options.sortBy = 'default'. We found that when sorting by creationTime instead, we saw an exception instead of a crash

I’m hoping that maybe this is a helpful enough lead for the Expo team? Are there any other scenarios that would helpful for us to test?

Screenshot_20201203-162754 Screenshot_20201203-162704

Additionally, here is the error that we see when the app does not crash:

"type":"error",
         "msg":"Error fetching gallery",
         "context":{
            "nativeStackAndroid":[
               {
                  "lineNumber":496,
                  "file":"IoBridge.java",
                  "methodName":"open",
                  "class":"libcore.io.IoBridge"
               },
               {
                  "lineNumber":159,
                  "file":"FileInputStream.java",
                  "methodName":"<init>",
                  "class":"java.io.FileInputStream"
               },
               {
                  "lineNumber":115,
                  "file":"FileInputStream.java",
                  "methodName":"<init>",
                  "class":"java.io.FileInputStream"
               },
               {
                  "lineNumber":7,
                  "file":"ExifInterface.java",
                  "methodName":"<init>",
                  "class":"b.k.a.a"
               },
               {
                  "lineNumber":14,
                  "file":"MediaLibraryUtils.java",
                  "methodName":"putAssetsInfo",
                  "class":"expo.modules.medialibrary.MediaLibraryUtils"
               },
               {
                  "lineNumber":12,
                  "file":"GetAssets.java",
                  "methodName":"doInBackground",
                  "class":"expo.modules.medialibrary.GetAssets"
               },
               {
                  "lineNumber":1,
                  "file":"GetAssets.java",
                  "methodName":"doInBackground",
                  "class":"expo.modules.medialibrary.GetAssets"
               },
               {
                  "lineNumber":378,
                  "file":"AsyncTask.java",
                  "methodName":"call",
                  "class":"android.os.AsyncTask$3"
               },
               {
                  "lineNumber":266,
                  "file":"FutureTask.java",
                  "methodName":"run",
                  "class":"java.util.concurrent.FutureTask"
               },
               {
                  "lineNumber":1167,
                  "file":"ThreadPoolExecutor.java",
                  "methodName":"runWorker",
                  "class":"java.util.concurrent.ThreadPoolExecutor"
               },
               {
                  "lineNumber":641,
                  "file":"ThreadPoolExecutor.java",
                  "methodName":"run",
                  "class":"java.util.concurrent.ThreadPoolExecutor$Worker"
               },
               {
                  "lineNumber":919,
                  "file":"Thread.java",
                  "methodName":"run",
                  "class":"java.lang.Thread"
               }
            ],
            "userInfo":null,
            "message":"Could not read file or parse EXIF tags",
            "code":"E_UNABLE_TO_LOAD",
            "line":29,
            "column":1111,
            "sourceURL":"/data/user/0/com.signpost.mobile.fusion/files/.expo-internal/bundle-0A567BD2F4A74BB1A60A2BC41735D0C12C756E26B5A74BD200CEF235320100ED"
         }
SnaiNeR commented 3 years ago

same issue on GetAssets function call, on prod builds on google play (android 10, "expo-media-library": "^8.1.0), but we can't to reproduce it on our local develop unfortunately "stackTrace": "java.lang.RuntimeException: An error occurred while executing doInBackground()\n\tat android.os.AsyncTask$4.done(AsyncTask.java:415)\n\tat java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)\n\tat java.util.concurrent.FutureTask.setException(FutureTask.java:252)\n\tat java.util.concurrent.FutureTask.run(FutureTask.java:271)\n\tat java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)\n\tat java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)\n\tat java.lang.Thread.run(Thread.java:923)\nCaused by: java.lang.IllegalArgumentException: Invalid column latitude\n\tat android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:172)\n\tat android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:142)\n\tat android.content.ContentProviderProxy.query(ContentProviderNative.java:472)\n\tat android.content.ContentResolver.query(ContentResolver.java:1183)\n\tat android.content.ContentResolver.query(ContentResolver.java:1115)\n\tat android.content.ContentResolver.query(ContentResolver.java:1071)\n\tat expo.modules.medialibrary.GetAssets.doInBackground(GetAssets.java:40)\n\tat expo.modules.medialibrary.GetAssets.doInBackground(GetAssets.java:21)\n\tat android.os.AsyncTask$3.call(AsyncTask.java:394)\n\tat java.util.concurrent.FutureTask.run(FutureTask.java:266)\n\t... 3 more\n",

SnaiNeR commented 3 years ago

UPDATE: as i rechecked in prod we used old version - "expo-media-library": "^8.1.0, and with "expo-media-library": "^9.2.1 there is no crash in Android 10, confirmed (in my case) @maxipetrucci was right :-)

VictorGuedes17 commented 3 years ago

I still have problems even upgrading to expo sdk 40.

"dependencies": { "expo": "~40.0.0", "expo-image-picker": "^9.2.0", "expo-media-library": "^10.0.0", }

The application crash with getAssetsAsync and deleteAssetsAsycn...

I'm testing with android 9 (Xaiomi mi 8 lite) and android 8 (Moto G).

Is there any other way to delete images from the gallery? Without it, the app will fill users' storage.

stale[bot] commented 3 years ago

It's been a while since we've had any activity on this issue, and seeing as it needs more info before we can properly address it, we will be closing it in one month. If you've found a fix, please share it! Otherwise, please provide the info we asked for, especially a reproducible example. Thanks!

stale[bot] commented 3 years ago

This issue has been automatically closed since there has not been any recent activity after it was marked as stale. Please open a new issue for any related bugs.

isotopeee commented 3 years ago

UPDATE: as i rechecked in prod we used old version - "expo-media-library": "^8.1.0, and with "expo-media-library": "^9.2.1 there is no crash in Android 10, confirmed (in my case) @maxipetrucci was right :-)

Works on Android 11 as well. This thread saved my life. 🙏