4

I'm trying to download and save a file with rn-fetch-blob. (I haven't been able to do it without a library since apparently react-native only implements a subset of the browser's fetch interface). My code is something like:

import RNFetchBlob from 'rn-fetch-blob' RNFetchBlob .config({ path: RNFetchBlob.fs.dirs.DocumentDir + '/medias/foo' }) .fetch('GET', 'http://example.com/files/foo', { 'Cache-Control': 'no-store' }) .then(res => { console.log('file saved to ' + res.path()) }) 

and I'm getting:

[RNFetchBlobRequest] session didCompleteWithError (null) [RNFetchBlobRequest] session didBecomeInvalidWithError (null) Possible Unhandled Promise Rejection (id: 0): Error: No such file '/Users/me/Library/Developer/CoreSimulator/Devices/0781956D-D2E6-4BC8-8943-62DA9B111BEF/data/Containers/Data/Application/A39E6A35-D248-4019-9CA0-1F9063E40161/Documents/medias/foo' Error: No such file '/Users/me/Library/Developer/CoreSimulator/Devices/0781956D-D2E6-4BC8-8943-62DA9B111BEF/data/Containers/Data/Application/A39E6A35-D248-4019-9CA0-1F9063E40161/Documents/medias/foo' at createErrorFromErrorData (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:1824:15) at http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:1777:25 at MessageQueue.__invokeCallback (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:2135:16) at http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:1952:16 at MessageQueue.__guard (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:2070:9) at MessageQueue.invokeCallbackAndReturnFlushedQueue (http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false:1951:12) at http://localhost:8081/debugger-ui/debuggerWorker.js:72:58 

The file is not created, the 'medias' directory in the (virtual) device remains empty.

How to download and save a file with react-native?

1

5 Answers 5

3

let try this.

import RNFetchBlob from 'rn-fetch-blob' import Share from 'react-native-share' import RNFS from 'react-native-fs' import {Alert, Platform} from 'react-native' const download = (url) => { let dirs = RNFetchBlob.fs.dirs try { if (Platform.OS === 'android') { const configOptions = { fileCache: true } RNFetchBlob.config(configOptions) .fetch('GET', url, { 'Authorization': '', //yourTokenIfHave 'Content-Type': '' // 'application/octet-stream' }) .then(resp => { return resp.readFile('base64') }) .then(async base64Data => { base64Data = `data:application/pdf;base64,` + base64Data await Share.open({ url: base64Data }) // remove the image or pdf from device's storage await RNFS.unlink(filePath) }) } else { RNFetchBlob .config({ fileCache: true, path: dirs.DocumentDir + `/${itemPDF.fileName}` }) .fetch('GET', url, { 'Authorization': '', 'Content-Type': '' // 'application/octet-stream' }) .then(async (res) => { // the temp file path if (res && res.path()) { const filePath = res.path() let options = { type: 'application/pdf', url: filePath } await Share.open(options) await RNFS.unlink(filePath) } }) .catch((error) => { console.log(error) }) } } catch (error) { console.log('download: ', error) } } 
Sign up to request clarification or add additional context in comments.

2 Comments

Your snippet has an indentation issue. But thanks for pointing to github.com/react-native-community/react-native-share , which is undoubtedly the cleanest way to save files since it asks the user where it wants to save it, and is cross-platform!
@ThomasP. They don't allow an option to save to camera roll which is what many of us want
1

I did not try again rn-fetch-blob, I ended up using react-native-fs and it works. react-native-fs seems more popular and more maintained.

(I did a react-native version upgrade before trying again to save a file, so maybe it wasn't entirely due to a bug in rn-fetch-blob but also due to using an old react-native version.)

Comments

0

You problem appears to be with the permissions access to that dir, .config({ path: RNFetchBlob.fs.dirs.DocumentDir + '/medias/foo' }), probably because /medias/foo does not exist, try to do it without a specific path.

I always use it in this way, as explained in the docs:

RNFetchBlob .config({ // add this option that makes response data to be stored as a file, // this is much more performant. fileCache : true, }) .fetch('GET', 'http://www.example.com/file/example.zip', { //some headers .. }) .then((res) => { // the temp file path console.log('The file saved to ', res.path()) }) 

3 Comments

This does not answer the question. I want my files in a specific location and not in random locations. I need to keep track of files easily.
then check if medias/foo is a valid path
Yes with a shell I can create files in medias/.
0

I had same issue, if you are using "rn-fetch-blob": 0.10.14 switch to "0.10.13", check https://github.com/joltup/rn-fetch-blob/issues/266 & https://github.com/wonday/react-native-pdf/issues/286

Comments

0

This is a sample function to download the file and save it to the appropriate file path. Keep in mind this is a generic function so please tweak it according to your use case.

const downloadFile = ({ fileExt }) => { ReactNativeBlobUtil.config({ fileCache: true, }).fetch('GET', filePath) .then(async(res) => { ToastAndroid.show('Download Successful', ToastAndroid.SHORT); // in iOS, we want to save our files by opening up the saveToFiles bottom sheet action. // whereas in android, the download manager is handling the download for us. if (Platform.OS === 'ios') { ReactNativeBlobUtil.ios.openDocument(res.data); } else { await ReactNativeBlobUtil.MediaCollection.copyToMediaStore({ name: fileName, parentFolder: `${ParentFolder}/${fileExt.toUpperCase()}`, // it will store the file in this path mimeType: fileType }, 'Download', // Media Collection to store the file in ("Audio" | "Image" | "Video" | "Download") res.path()); } }) .catch((err) => console.log('BLOB ERROR -> ', err)); }

Keep in mind copying to the media store is the most important part. You can also ask for storage permissions from the user before downloading.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.