53

I am building an app with React Native, for Android and iOS. I am trying to let the user download a PDF file when clicking on a button.

  • react-native-file-download does not support Android
  • react-native-fs does nothing when I trigger downloadFile (nothing shows up on the notification bar), and I am not able to find the file after that. I added android.permission.WRITE_EXTERNAL_STORAGE to the Android Manifest file. I double-checked that the file I am trying to download exists (when it does not, the library throws an error)

I do not find other solutions for this problem. I have found libraries for viewing a PDF, but I would like to let the user download the PDF.

halfer
  • 19,824
  • 17
  • 99
  • 186
Arnaud
  • 4,884
  • 17
  • 54
  • 85

5 Answers5

60

Follow these steps:

  1. Run npm install rn-fetch-blob.

  2. Follow the installation instructions. If you want to manually install the package without using rnpm, go to their wiki.

  3. Finally, that's how I made it possible to download files within my app:

    const { config, fs } = RNFetchBlob
    let PictureDir = fs.dirs.PictureDir // this is the pictures directory. You can check the available directories in the wiki.
    let options = {
      fileCache: true,
      addAndroidDownloads : {
        useDownloadManager : true, // setting it to true will use the device's native download manager and will be shown in the notification bar.
        notification : false,
        path:  PictureDir + "/me_"+Math.floor(date.getTime() + date.getSeconds() / 2), // this is the path where your downloaded file will live in
        description : 'Downloading image.'
      }
    }
    config(options).fetch('GET', "http://www.example.com/example.pdf").then((res) => {
      // do some magic here
    })
    
double-beep
  • 5,031
  • 17
  • 33
  • 41
Ray
  • 9,184
  • 3
  • 27
  • 44
  • 1
    No address associated with hostname getting this error how to resolve it – Rajat Gupta Jun 07 '18 at 06:43
  • 5
    *addAndroidDownloads* It's just download for Android, what about iOS? – Hoàng Vũ Anh Aug 31 '18 at 04:07
  • 3
    react-native-fetch-blob is deprecated use rn-fetch-blob instead – JXLai Oct 15 '18 at 09:54
  • 1
    @Ray I believe this is a workout for android. How about if we want the same to work on ios? I am trying to download an Image from url and display in the device, can you help me out? – Abhirup Mukherjee Jul 11 '19 at 06:35
  • 1
    @Ray I am unable to download pdf files on http domain (eg. `http://www.africau.edu/images/default/sample.pdf`) in MI A1 with Android 9 (Pie) version. Though, I am able to download https domain pdf files (eg. `https://file-examples-com.github.io/uploads/2017/10/file-sample_150kB.pdf`) on the same device. Please, help me out for http ones. I have also referred to https://github.com/joltup/rn-fetch-blob/issues/351 and posted [here](https://github.com/joltup/rn-fetch-blob/issues/677) but still no luck. – Narendra Singh Sep 30 '20 at 08:30
  • I have 'POST' request type to download file how can I download ? please suggest – Chandni Dec 02 '20 at 04:15
  • Hi, i'm using this approach but I can't download files that are bigger than 2MB, any sugestions? With postman I can download normally. I have a code 16 error on my console. Thanks – Gabriel Augusto Mar 26 '21 at 17:59
28

If you're using Expo, react-native-fetch-blob won't work. Use FileSystem.

Here's a working example:

const { uri: localUri } = await FileSystem.downloadAsync(remoteUri, FileSystem.documentDirectory + 'name.ext');

Now you have localUri with the path to the downloaded file. Feel free to set your own filename instead of name.ext.

AmerllicA
  • 29,059
  • 15
  • 130
  • 154
Fancy John
  • 38,140
  • 3
  • 27
  • 27
6

I Followed the solution from Jonathan Simonney, above on this post. But I had to change it a little:

const { config, fs } = RNFetchBlob;
  const date = new Date();

  const { DownloadDir } = fs.dirs; // You can check the available directories in the wiki.
  const options = {
    fileCache: true,
    addAndroidDownloads: {
      useDownloadManager: true, // true will use native manager and be shown on notification bar.
      notification: true,
      path: `${DownloadDir}/me_${Math.floor(date.getTime() + date.getSeconds() / 2)}.pdf`,
      description: 'Downloading.',
    },
  };

  config(options).fetch('GET', 'http://www.africau.edu/images/default/sample.pdf').then((res) => {
    console.log('do some magic in here');
  });
1

I had the same issue, got it working using Expo WebBrowser Module

// install module 
npm install react-native-webview

// import the module
import * as WebBrowser from 'expo-web-browser';

// then in your function you can call this function
await WebBrowser.openBrowserAsync(file_ur);

it will open preview of the file and then user can download using share button.

Sameer Ali
  • 11
  • 1
1
  GetItem_downloadbtn = (item, itemname) => {
    console.log("fiel url comiugn jdd   " + item);
    console.log("item name checkoing " + itemname);
    const android = RNFetchBlob.android;
    const filename = itemname;
    const filepath = RNFetchBlob.fs.dirs.DownloadDir + '/foldernamae/' + filename;
    const downloadAppUrl = item;

    RNFetchBlob.config({
        addAndroidDownloads: {
            useDownloadManager: true,
            title: 'great, download success',
            description:'an apk that will be download',
            mime: 'application/vnd.android.package-archive',
            // mime: 'image/jpeg',
            // mediaScannable: true,
            notification: true,
            path: filepath
        }
    })
    .fetch('GET', downloadAppUrl)
    .then((res) => {
        // console.log('res.path ', res.path());
        alert('res.path ', res.path());
        android.actionViewIntent(res.path(), 'application/vnd.android.package-archive');
    })
    .catch((err) => {
        alert('download error, err is', JSON.stringify(err));
    });
  }
GUGAN RAJ
  • 101
  • 7