Unable to download file in expected location

I am new to expo sorry if this question is duplicate, I want to download video/ any file into my gallery, the expo doesn’t not providing doc’s clearly its says only downloading file in cache.
I am trying this way but I couldn’t.
Can you please help me someone.
const { uri } = await camera.takePictureAsync();
const asset = await MediaLibrary.createAssetAsync(uri);
FileSystem.downloadAsync(
https://s3.amazonaws.com/dancebook-development/mov.mp4’,
asset
)
.then(({ uri }) => {
console.log('Finished downloading to ', uri);
})
.catch(error => {
console.error(error);
});
I am getting this error: Unhandled promise rejection: Error: Unable to copy file into external storage.]

Hi @nmanthena, sorry for the question but do you want to take a picture then save it the galery or just download a video from the link above

@fredius i want to download video/ any file from the link.

@nmanthena if you just want to download an image you can do it like this

_downloadPic = async () => {

    const link =
      "https://images.unsplash.com/photo-1542838077-7fb322b21b80?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1233&q=80";

//access the local directory link
    const myFolder = FileSystem.documentDirectory;
//then download the file
    const resp = await FileSystem.downloadAsync(link, `${myFolder}/img.jpg`);
//update the state if you want to display the file directly
    this.setState({ img: resp });
  };

@fredius Thanks for your response,
The example given by you still its downloading the file in temp/catch folder (“uri”: “file:///data/user/0/host.exp.exponent/files/ExperienceData/%2540something%252Fapp/img.jpg”). but i want this file into gallery or downloads folder or any media folder is this possible with expo?

Hi @nmanthena try this function. I am note sure if the Permission is required so you can also try without ii :grin:

_downloadFile = async () => {
    const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL);

//permission for camera_roll
    if (status === "granted") {
//store the cached file
      const file = await FileSystem.downloadAsync(
        link,
        FileSystem.documentDirectory + "filename.jpg"
      );

//save the image in the galery using the link of the cached file
      const assetLink = await MediaLibrary.createAssetAsync(file.uri);
      console.log(file, assetLink);
    }
  };
2 Likes

@fredius thanks for your reply let me give a try with this.

1 Like

@nmanthena Ok

Thanks @fredius awesome its working the downloaded file appear somewhere in the storage, can we do something for CSV/PDF files because I have to download csv or pdf file inside the download folder when user clicking on the button. could you please help me in that.

Hi,

The easiest way

import { Linking } from 'react-native'; Linking.openURL(pdfurl);

3 Likes

Thanks @batmat the given approach is working thanks lot.

1 Like

@batmat and @fredius Can we create a file like PDF/CSV, for example I am getting same base64 data from server I want convert it into file Csv/Pdf and download it.

@nmanthena Hi, maybe you could try to open it as Data uri scheme with Linking.openURL. (didn’t try)

data :[ <media type> ][ ;base64 ], <data>

Otherwise you should make an endpoint on your server, or store it in a service such amazon s3.

@fredius solution works, thanks!

but, it saves the file in DCIM folder.

if someone wants to move it to another folder you can do this, but bear it mind it just makes a copy into the new folder name "NEWFOLDER’ below:

const location = await FileSystem.downloadAsync(
                    uri,
                    // FileSystem.cacheDirectory + fileName,
                    FileSystem.documentDirectory + fileName,
                );
                console.log('Finished downloading to ', location);


                const assetLink = await MediaLibrary.createAssetAsync(location.uri);

                MediaLibrary.createAlbumAsync('NEWFOLDER', assetLink)

                alert(`Image downloaded to the NEWFOLDER folder in your phone:  ${assetLink.filename}`)

unable to delete it from DCIM folder, so I have two copies now.

Thank you @fredius, I tried your functions and it worked well on Android but unfortunately, got this error on IOS:
Save error: [Error: Asset couldn’t be saved to photo library]

Here is my code:

const saveFile = async (fileUri) => {
    const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL);
    if (status === "granted") {
        try{
            const asset = await MediaLibrary.createAssetAsync(fileUri);
            await MediaLibrary.createAlbumAsync("Download", asset, false);
            alert("Success", "Image was successfully downloaded!");
        }catch(err){
            console.log("Save error: ", err)
        }
      
    }
  }
 const downloadFileHandler = async (uri) =>{

    let fileUri = FileSystem.documentDirectory + 'test.mp4';

    try {
        const res = await FileSystem.downloadAsync(uri, fileUri)
        saveFile(res.uri)
        console.log(res.uri)
    }   catch(err){
        console.log("FS Err: ", err)
    }

}

Has anyone face it before?

Problem solved!

Please refer to this thread