9

I downloaded an image(a.jpg) using expo using the code:

 FileSystem.downloadAsync(
                    httpUrl,
                    FileSystem.documentDirectory + location
                ).then((result)=>{
                    const uri = result.uri;
                }).catch((err)=>{
                    console.log("​getFile -> err", err);}
);

The file is successfully saved in the file system. Later when I try to read the file, I get an error that file couldn't be read. Code used to read the file:

const fileInfo = await FileSystem.getInfoAsync(uri);
if(fileInfo.exists){
            FileSystem.readAsStringAsync(uri).then(data => {
                const base64 = 'data:image/jpg;base64' + data;
                resolve(data) ; 
            }).catch(err => {
                console.log("​getFile -> err", err);
                reject(err) ;
            });
 }

The above code returns an error that file couldn't be read. fileInfo.exists is true as the file exists in the file system.

 ​getFile -> fileInfo Object {
    "exists": 1,
     "isDirectory": false,
     "modificationTime": 1547272322.8714085,
     "size": 51725,
    "uri": "file:///Users/deeparora/Library/Developer/CoreSimulator/Devices/A2DC4519-       C18C-4512-8C23-E624A1DAA506/data/Containers/Data/Application/6D7B23AA-      A555-4F9A-B9D1-EB5B9443CCB6/Documents/ExponentExperienceData/       %2540anonymous%252Fhola-vet-6faee8ac-e309-4d5b-a1c0-6f8688f8a508/a.jpg",
:}

Error when reading the file:

err [Error: File 'file:///Users/deeparora/Library/Developer/CoreSimulator/Devices/A2DC4519-C18C-4512-8C23-E624A1DAA506/data/Containers/Data/
Application/6D7B23AA-A555-4F9A-B9D1-EB5B9443CCB6/
Documents/ExponentExperienceData/%2540anonymous%252Fhola-vet-6faee8ac-e309-4d5b-a1c0-6f8688f8a508/a.jpg' could not be read.]

If instead of jpg(a.jpg), I try to read a text file(a.json), everything works well. So, FileSystem.readAsStringAsync works fine for the text file, not for jpg. May be, there is need to provide other parameters as options to this methods for it to read jpg as base64 string.

Deep Arora
  • 1,900
  • 2
  • 24
  • 40
  • For those who need to read in the content of an image from Expo's Image Picker, you can get the content for free: simply set launchImageLibraryAsync()/launchCameraAsync()'s base64 to true and then retrieve the Base64 data from the response's base64 field. – Caleb Koch Dec 05 '21 at 03:54

1 Answers1

12

It's due to the fact that you are not telling FileSystem.readAsStringAsync that the encoding type that you require is base64.

Try using

let options = { encoding: FileSystem.EncodingTypes.Base64 };
FileSystem.readAsStringAsync(uri, options).then(data => {
            const base64 = 'data:image/jpg;base64' + data;
            resolve(base64); // are you sure you want to resolve the data and not the base64 string? 
        }).catch(err => {
            console.log("​getFile -> err", err);
            reject(err) ;
        });

You can see more about the different options in the docs. https://docs.expo.io/versions/latest/sdk/filesystem#expofilesystemreadasstringasyncfileuri-options

Here is a snack of it working with async/await https://snack.expo.io/Hk-m38wfN

Andrew
  • 26,706
  • 9
  • 85
  • 101
  • I tried this also earlier and again, but I get an error on this line: const options = { encoding: FileSystem.EncodingTypes.Base64 }; //[TypeError: undefined is not an object (evaluating '_expo.FileSystem.EncodingTypes.Base64')] – Deep Arora Jan 12 '19 at 16:03
  • It appears that base64 support in FileSystem is added in expo 31.0.0 (https://blog.expo.io/expo-sdk-v31-0-0-is-now-available-cad6d0463f49). I was using an earlier version of expo, hence getting the error when passing options as a parameter. – Deep Arora Jan 12 '19 at 16:12
  • That’s good to know. Are you able to upgrade your expo version? – Andrew Jan 12 '19 at 16:17
  • Yea, I updated to 31.0.0 and FileSystem is able to load jpg file as base64 string. – Deep Arora Jan 12 '19 at 18:38