React Native Download File/Image
Tags: reactnative, javascript
Published: 2024-01-12 08:42:04

## LIBRARY USED:
[react-native-blob-util
](https://www.npmjs.com/package/react-native-blob-util)

---

## INSTALLATION:

```
yarn add react-native-blob-util react-native-device-info moment && cd ios && pod install
```

---

## CONFIGURATION:

**a) In ANDROID:**

Add permission in `AndroidManifest.xml`

```
    <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="32" /> 
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="29" />
    <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />

```

**b) In iOS:**

Add in `info.plist`

```
<dict>
....
	<key>LSSupportsOpeningDocumentsInPlace</key>
	<true/>
	<key>UIFileSharingEnabled</key>
	<true/>
...
</dict>
```

---

## Helper File

```
import { Platform, PermissionsAndroid, Alert } from 'react-native';
import ReactNativeBlobUtil from 'react-native-blob-util';
import moment from 'moment';
import { getSystemVersion } from 'react-native-device-info';
import { isAndroid } from './helper';

const downloadFileWithPermission = async ({ url, fileType, filename = '' }) => {
  if (isAndroid()) {
    const deviceVersion = getSystemVersion();
    let granted = PermissionsAndroid.RESULTS.DENIED;
    if (deviceVersion >= 13) {
      granted = PermissionsAndroid.RESULTS.GRANTED;
    } else {
      granted = await PermissionsAndroid.request(
        PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE,
        {
          title: 'Storage Permission',
          message: 'App needs access to your storage to download files.',
          buttonNeutral: 'Ask Me Later',
          buttonNegative: 'Cancel',
          buttonPositive: 'OK',
        }
      );
    }
    if (granted) {
      downloadFile(url, fileType, filename);
    } else {
      Alert.alert('Permission Denied', 'Storage permission is required to download files.');
    }
  } else {
    // Handle permissions for iOS or other platforms if needed
    // iOS issue fix ref: https://stackoverflow.com/a/54627588/9377254
    downloadFile(url, fileType, filename);
  }
};

const downloadFile = (url, fileType, filename) => {
  try {
    let extension = null;
    switch (fileType) {
      case 'image':
        extension = 'jpg';
        break;
      case 'pdf':
        extension = 'pdf';
        break;
      case 'doc':
      case 'docx':
        extension = fileType;
        break;
      default:
        // You can add more cases for different file types
        break;
    }

    if (!extension) {
      throw new Error(`Unsupported file extension: ${fileType}`);
    }

    const {
      dirs: { DownloadDir, DocumentDir },
    } = ReactNativeBlobUtil.fs;
    const { config } = ReactNativeBlobUtil;
    const aPath = Platform.select({ ios: DocumentDir, android: DownloadDir });
    const fPath = `${aPath}/${filename}-${moment().format()}.${extension}`;

    const configOptions = Platform.select({
      ios: {
        fileCache: true,
        path: fPath,
        // mime: 'application/xlsx',
        // appendExt: 'xlsx',
        // path: filePath,
        // appendExt: fileExt,
        notification: true,
      },

      android: {
        fileCache: false,
        addAndroidDownloads: {
          useDownloadManager: true,
          notification: true,
          path: fPath,
          description: 'Downloading...',
        },
      },
    });

    if (aPath && fPath) {
      config(configOptions)
        .fetch('GET', url, {})
        .progress((_received, _total) => {
          console.log('ReactNativeBlobUtil PROGRESS: ', _received, _total);
        })
        .then((_res) => {
          alert(JSON.stringify(_res));
          console.log('Success: ', _res, fPath);
        });
    } else {
      throw new Error('Directory not found');
    }
  } catch (error) {
    console.log('ReactNativeBlobUtil ERROR: ', error.message);
    return null;
  }
};

export { downloadFileWithPermission };
```

---

## USAGE:

```
    const downloadImage = {
      url: 'https://picsum.photos/200/300',
      filename: 'newImage',
      fileType: 'image',
    };

    const downloadPDF = {
       url: 'https://www.africau.edu/images/default/sample.pdf',
       fileType: 'pdf', // image
       filename: 'sample',
     };
    downloadFileWithPermission(downloadImage);
    downloadFileWithPermission(downloadPDF);

```