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
32.7k stars 5.2k forks source link

[expo-file-system] Location ... isn't readable. #17810

Closed dmitryusikriseapps closed 2 years ago

dmitryusikriseapps commented 2 years ago

Summary

Hey guys. Method getInfoAsync throws an error on Android. It worked well with the previous version of the SDK.

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)

45

Environment

expo-env-info 1.0.3 environment info: System: OS: macOS 12.4 Shell: 5.8.1 - /bin/zsh Binaries: Node: 16.5.0 - /usr/local/bin/node Yarn: 1.22.18 - /usr/local/bin/yarn npm: 8.6.0 - /usr/local/bin/npm Watchman: 2022.03.21.00 - /usr/local/bin/watchman Managers: CocoaPods: 1.11.2 - /usr/local/bin/pod SDKs: iOS SDK: Platforms: DriverKit 21.4, iOS 15.5, macOS 12.3, tvOS 15.4, watchOS 8.5 IDEs: Android Studio: 2021.1 AI-211.7628.21.2111.8193401 Xcode: 13.4.1/13F100 - /usr/bin/xcodebuild npmPackages: babel-preset-expo: ~9.1.0 => 9.1.0 expo: ^45.0.0 => 45.0.4 react: 17.0.2 => 17.0.2 react-native: 0.68.2 => 0.68.2 npmGlobalPackages: eas-cli: 0.52.0 expo-cli: 5.4.6 Expo Workflow: managed

Reproducible demo

It's possible to create a new directory and I can get access to it with the Android Studio file manager, but when I'm trying to access it with getInfoAsync it throws an error. I attached the screenshots.

await FileSystem.makeDirectoryAsync(userDirectory, { intermediates: true });
const info = await FileSystem.getInfoAsync(userDirectory);
Screenshot 2022-06-10 at 15 23 09 Screenshot 2022-06-10 at 15 23 34
dmitryusikriseapps commented 2 years ago

The issue is resolved now. The reason was a : sign in the path. Maybe it'll be useful for somebody else.

Simek commented 2 years ago

Hello @dmitryusikriseapps, I'm happy to see that you were able to fix the problem.

Colon character is a known restricted character for the HFS+/AFS file systems (macOS & iOS) and it's not the limitation which came from using Expo.

gasparnd commented 2 years ago

@Simek @dmitryusikriseapps Hey there, same problem here. I have the lates expo version and i cant upload a video with FileSystem.uploadAsync. In the prev version of the app (SDK 44) this worked perfectly. Error:

[Error: Location 'file:///data/user/0/host.exp.exponent/cache/ImagePicker/beb3466a-756f-4198-b0e9-ca91f08ed6ad.mp4' isn't readable.]

Enviroment: Windows 10, Node: v16.17.0, nom: v8.17.0 Dependencies:

    "expo": "~46.0.8",
    "expo-image-picker": "~13.3.1",
    "expo-file-system": "~14.1.0",
    "react": "18.0.0",
    "react-dom": "18.0.0",
    "react-native": "0.69.4",

Code:

const handelUploade = async (uri: string) => {
    try {
      const headers = {
        Accept: "application/json",
        "Content-Type": "multipart/form-data",
      };

      const res = await FileSystem.uploadAsync(
        "https://aa09-190-211-90-90.ngrok.io/uploadVideo",
        uri,
        {
          httpMethod: "POST",
          uploadType: FileSystemUploadType.MULTIPART,
          fieldName: "file",
          headers: headers,
        }
      );

      if (res) {
        return res;
      }
    } catch (error) {
      console.log(
        "🚀 ~ file: App.tsx ~ line 49 ~ handelUploade ~ error",
        error
      );
      Alert.alert("Somthing is wrong");
    }
  };
devyuvraj4 commented 2 years ago

@Simek @dmitryusikriseapps Hey there, same problem here. I have the lates expo version and i cant upload a video with FileSystem.uploadAsync. In the prev version of the app (SDK 44) this worked perfectly. Error:

[Error: Location 'file:///data/user/0/host.exp.exponent/cache/ImagePicker/beb3466a-756f-4198-b0e9-ca91f08ed6ad.mp4' isn't readable.]

Enviroment: Windows 10, Node: v16.17.0, nom: v8.17.0 Dependencies:

    "expo": "~46.0.8",
    "expo-image-picker": "~13.3.1",
    "expo-file-system": "~14.1.0",
    "react": "18.0.0",
    "react-dom": "18.0.0",
    "react-native": "0.69.4",

Code:

const handelUploade = async (uri: string) => {
    try {
      const headers = {
        Accept: "application/json",
        "Content-Type": "multipart/form-data",
      };

      const res = await FileSystem.uploadAsync(
        "https://aa09-190-211-90-90.ngrok.io/uploadVideo",
        uri,
        {
          httpMethod: "POST",
          uploadType: FileSystemUploadType.MULTIPART,
          fieldName: "file",
          headers: headers,
        }
      );

      if (res) {
        return res;
      }
    } catch (error) {
      console.log(
        "🚀 ~ file: App.tsx ~ line 49 ~ handelUploade ~ error",
        error
      );
      Alert.alert("Somthing is wrong");
    }
  };

did you get the solution for this beacuse i am also facing the same issue as i update my app to 46 Sdk it was working on 44

aleqsio commented 2 years ago

Think this issue is also tracked here: https://github.com/expo/expo/issues/18760

devyuvraj4 commented 2 years ago

I used ImageManipulator of expo now is working fine

`const pickImage = async () => { let permissionResult = await ImagePicker.requestMediaLibraryPermissionsAsync(); if (permissionResult.granted === false) { alert("Permission to access camera roll is required!"); return; }

let result = await ImagePicker.launchImageLibraryAsync({
  mediaTypes: ImagePicker.MediaTypeOptions.Images,
  allowsEditing: true,
  aspect: [4, 4],
  quality: 1,
});

if (!result.cancelled) {
  const manipResult = await ImageManipulator.manipulateAsync(
    result.localUri || result.uri,
    [{resize: {height:500,  width:500}}],
    { compress: 1, format: ImageManipulator.SaveFormat.PNG },
  );
  setImage(manipResult);
};

}; ` i dont know why is working now and why not expo image picker

vladotoka commented 1 year ago

I upgrade Expo SDK from 44 to 46 and have the same problem. i don't find any other solution than use dummy pseudo image manipulation middleware - without any real image manipulations . Thank you @Yuvrajedulab :)

` const image = await ImagePicker.launchCameraAsync({ allowsEditing: true, aspect: [16, 9], quality: 0.5, });

    if (!image.cancelled) {
        // dummy fixing ImagePicker bug in EXPO SDK46
        //TODO remove this bugfix with next EXPO SDK release
        const dummyManipulationResult = await ImageManipulator.manipulateAsync(
            image.uri,
            [],
            {}
        );
        //end of dummy fix...

        // setPickedImage(image.uri);
        // props.onImageTaken(image.uri);

        setPickedImage(dummyManipulationResult.uri);
        props.onImageTaken(dummyManipulationResult.uri);
    }

`

Acex187x commented 1 year ago

Getting this problem sometimes using "expo-image-picker" using 46 SDK and Android Emulator, trying to upload the file to the server right after taking a photo from the camera

filipeleonelbatista commented 1 year ago

I have an application where I want to load a CSV into the app's memory. I'm using expo and expo-document-picker. It is returning OK the object with the cached file address, however when I read using expo-file-system it gives an error. Here's the code snippet.


            let result = await DocumentPicker.getDocumentAsync({
                type: 'text/comma-separated-values',
                copyToCacheDirectory: true,
                multiple: false,
            });

            console.log(result);
            // Console.log
            // > {"mimeType": "text/comma-separated-values", "name": "financas.CSV", "size": 592, "type": "success", "uri": "file:///data/user/0/host.exp.exponent/cache/DocumentPicker/d37cb00e-4ab4-4b79-9650-0aac15f8a92c.CSV"}

            if (result.type === 'success') {
                let fileContent = await FileSystem.readAsStringAsync(result.uri, { encoding: 'utf8' });
                // Console.log
                // [Error: Location 'file:///data/user/0/host.exp.exponent/cache/DocumentPicker/d37cb00e-4ab4-4b79-9650-0aac15f8a92c.CSV' isn't readable.]
                console.log(fileContent);

Using SDK48 expo and all latest libs.

Rishiry commented 1 year ago

I'm having the same issue as @filipeleonelbatista. The FileSystem.readAsStringAsync function is throwing an error, however, only on android. iOS seems to work just fine.

gusta262 commented 1 year ago

@filipeleonelbatista did you find any solution? I have the same problem but with pdf file

twwspes commented 1 year ago

@filipeleonelbatista I am not sure if I have seen a similar issue.

In my case, I have got an Expo 48 app for iOS and Android trying to use expo-document-picker to pickup a document, an xlsx file to be precise, and read it from cache using expo-file-system

The codes worked perfectly in iOS Expo Go with simulator but it kept throwing the following error under Android Expo Go with emulator.

Error: Location 'file:///data/user/0/host.exp.exponent/cache/DocumentPicker/3d2d0935-2be8-43c8-93e9-885c0a7c24b7.xlsx' isn't readable

Then I tried to find a folder file:///data/user/0/host.exp.exponent/cache/DocumentPicker using expo-file-system but it seems it had difficulty accessing it.

But when I built a standalone version of apk and installed it in emulator, it works like a charm.

Rishiry commented 1 year ago

I would get the same error when trying to read a file:// uri with the readAsStringAsync function on Android. The following solution seems to work for me:

import { Platform } from "react-native";
import * as FileSystem from "expo-file-system";
// the file you are trying to read; usually starts with file://
var file_path;

if (Platform.OS === "android") {
  // change the file:// to content:// uri
  FileSystem.getContentUriAsync(file_path).then((uri) => {file_path = uri});
}

// now it works
FileSystem.readAsStringAsync(file_path, { encoding: "base64" }).then((data) => {
  // handle file
})
rodrix commented 1 year ago

Same here using SDK48.

When I run the app through Expo Go on Android, getting the same error as above.

I tried the above @Rishiry workaround, but got another error when using the FileSystem.getContentUriAsync: [Unhandled promise rejection: Error: Location 'file:///data/user/0/host.exp.exponent/cache/ImageManipulator/ab23bc1f-0dc7-4d2e-ae5a-4d03995814ea.png' isn't writable.]

On standalone builds seem to work fine.

So weird.

carlaTatiana commented 1 year ago

Same issue here using SDK 48. On expo go is failing but on standalone builds is working as expected.

aleqsio commented 1 year ago

@carlaTatiana Can you test it in SDK49 beta?

carlaTatiana commented 1 year ago

@carlaTatiana Can you test it in SDK49 beta?

I can't test it on SDK 49 yet.

Here is an open issue similar to this

gabrielyotoo commented 1 year ago

Any solutions for that? I'm facing this issue running my app in Expo Go Expo SDK: 48

Dart-Sharma commented 10 months ago

Read Excel file in expo go-[solved isn't readable error]

import React, { useState } from 'react'; import { Button, View } from 'react-native'; import as XLSX from 'xlsx'; import { Buffer } from 'buffer'; import as DocumentPicker from 'expo-document-picker'; import * as FileSystem from 'expo-file-system';

export default function App() { const FileUpload = async () => { let res = null; try { res = await DocumentPicker.getDocumentAsync({ type: '/', copyToCacheDirectory: true, multiple: false, }); if (res.canceled) { return; } const filePath = res.assets[0].uri; const fileContent = await FileSystem.readAsStringAsync(filePath, { encoding: FileSystem.EncodingType.Base64, }); const binaryString = Buffer.from(fileContent, 'base64').toString('binary'); const workbook = XLSX.read(binaryString, { type: 'binary' }); const worksheet = workbook.Sheets[workbook.SheetNames[0]]; const jsonData = XLSX.utils.sheet_to_json(worksheet); console.log(jsonData); } catch (err) { console.log('error -----', err); } };

return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <Button title='Pick an Excel file' onPress={() => FileUpload()} /> ); }`

3levate commented 1 week ago

I have an application where I want to load a CSV into the app's memory. I'm using expo and expo-document-picker. It is returning OK the object with the cached file address, however when I read using expo-file-system it gives an error. Here's the code snippet.

            let result = await DocumentPicker.getDocumentAsync({
                type: 'text/comma-separated-values',
                copyToCacheDirectory: true,
                multiple: false,
            });

            console.log(result);
            // Console.log
            // > {"mimeType": "text/comma-separated-values", "name": "financas.CSV", "size": 592, "type": "success", "uri": "file:///data/user/0/host.exp.exponent/cache/DocumentPicker/d37cb00e-4ab4-4b79-9650-0aac15f8a92c.CSV"}

            if (result.type === 'success') {
                let fileContent = await FileSystem.readAsStringAsync(result.uri, { encoding: 'utf8' });
                // Console.log
                // [Error: Location 'file:///data/user/0/host.exp.exponent/cache/DocumentPicker/d37cb00e-4ab4-4b79-9650-0aac15f8a92c.CSV' isn't readable.]
                console.log(fileContent);

Using SDK48 expo and all latest libs.

Need to do result.assets[0].uri as DocumentPicker.getDocumentAsync returns an array containing the files picked. Since there is only one file, select the first item in the assets array and then the uri