Hello guys, we all have heard about a famous react native NPM library rn-fetch-blob. This library comes with amazing possibilities and features which make easy to use it for beginners. In this tutorial we would Download Image from URL into Gallery folder and save the image in downloads folder. First we would send the request to sever and fetch the file, after fetching the file we would rename the file using individual functions so each time if the file has same name on server we would rename the file in random order and save in our mobile phone’s downloads folder. So let’s get started :).
Note: Guys there is a problem with rn-fetch-blob library because it is not working properly in iOS devices. So for now the code is only working in Android devices.
Content in this project React native Download Image from URL into Gallery folder Android iOS Example Tutorial:
1. Open your react native project folder in command prompt like i did in below screenshot and execute below command to install the rn-fetch-blob library.
1 |
npm install --save rn-fetch-blob |
Screenshot of CMD:
1 |
react-native link rn-fetch-blob |
Screenshot of CMD:
3. Now your library is successfully linked to your current react native project. Next step is to open the AndroidManifest.xml file located in Your_React_Native_Project -> android -> app -> src -> main -> AndroidManifest.xml .
4. Put the below WRITE_EXTERNAL_STORAGE permission in it. This permission is required for accessing device storage.
1 |
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> |
5. We need to also add a intent filter named as DOWNLOAD_COMPLETE in intent section.
1 |
<action android:name="android.intent.action.DOWNLOAD_COMPLETE"/> |
Source code of my AndroidManifest.xml file after making changes:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.project60"> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <application android:name=".MainApplication" android:label="@string/app_name" android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher_round" android:allowBackup="false" android:theme="@style/AppTheme"> <activity android:name=".MainActivity" android:label="@string/app_name" android:configChanges="keyboard|keyboardHidden|orientation|screenSize" android:windowSoftInputMode="adjustResize"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> <action android:name="android.intent.action.DOWNLOAD_COMPLETE"/> </intent-filter> </activity> <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" /> </application> </manifest> |
6. Now its time to start coding. Open your project’s App.js file, Delete all the previous code to start with clean slate. Import StyleSheet, Text, View, TouchableOpacity, Alert, PermissionsAndroid and Image component in your project.
1 2 3 |
import React, { Component } from 'react'; import { StyleSheet, Text, View, TouchableOpacity, Alert, PermissionsAndroid, Image } from 'react-native'; |
7. Import RNFetchBlob component from rn-fetch-blob library.
1 |
import RNFetchBlob from 'rn-fetch-blob'; |
8. Create a ASYNC stand alone function named as request_storage_runtime_permission(). In this function we would request for android’s runtime permission for accessing device storage. If you wish to learn more about how to request runtime permission in react native for android read my this tutorial.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
export async function request_storage_runtime_permission() { try { const granted = await PermissionsAndroid.request( PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE, { 'title': 'ReactNativeCode Storage Permission', 'message': 'ReactNativeCode App needs access to your storage to download Photos.' } ) if (granted === PermissionsAndroid.RESULTS.GRANTED) { Alert.alert("Storage Permission Granted."); } else { Alert.alert("Storage Permission Not Granted"); } } catch (err) { console.warn(err) } } |
9. Create your main export default class named as MainActivity. This would be our main class.
1 2 3 4 5 |
export default class MainActivity extends Component { } |
10. In MainActivity class create ASYNC componentDidMount() method and call the request_storage_runtime_permission() function using await method. This method will allow us to ask for runtime permission.
1 2 3 4 5 |
async componentDidMount() { await request_storage_runtime_permission() } |
11. Create a function named as downloadImage() in your Main class. In this function we would pass the Image HTTP URL which we want to download and simply shows a alert after download complete.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
downloadImage = () => { var date = new Date(); var image_URL = 'https://reactnativecode.com/wp-content/uploads/2018/02/motorcycle.jpg'; var ext = this.getExtention(image_URL); ext = "." + ext[0]; const { config, fs } = RNFetchBlob; let PictureDir = fs.dirs.PictureDir let options = { fileCache: true, addAndroidDownloads: { useDownloadManager: true, notification: true, path: PictureDir + "/image_" + Math.floor(date.getTime() + date.getSeconds() / 2) + ext, description: 'Image' } } config(options).fetch('GET', image_URL).then((res) => { Alert.alert("Image Downloaded Successfully."); }); } |
12. Create another function named as getExtention() in your main class. Using this function we would get the file extension.
1 2 3 4 |
getExtention = (filename) => { return (/[.]/.exec(filename)) ? /[^.]+$/.exec(filename) : undefined; } |
13. Creating a Image component & Touchable opacity button in render’s return block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
render() { return ( <View style={styles.MainContainer}> <Image source={{ uri: 'https://reactnativecode.com/wp-content/uploads/2018/02/motorcycle.jpg' }} style={{ width: 300, height: 300, resizeMode: 'contain', margin: 5 }} /> <TouchableOpacity style={styles.button} onPress={this.downloadImage} > <Text style={styles.text}>Click Here To Download Above Image</Text> </TouchableOpacity> </View> ); } |
14. Creating Style.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
const styles = StyleSheet.create({ MainContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', }, button: { width: '80%', paddingTop: 3, paddingBottom: 3, backgroundColor: '#2E7D32', borderRadius: 7, margin: 10 }, text: { color: '#fff', fontSize: 20, textAlign: 'center', padding: 5 } }); |
15. Complete source code for App.js File :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
import React, { Component } from 'react'; import { StyleSheet, Text, View, TouchableOpacity, Alert, PermissionsAndroid, Image } from 'react-native'; import RNFetchBlob from 'rn-fetch-blob'; export async function request_storage_runtime_permission() { try { const granted = await PermissionsAndroid.request( PermissionsAndroid.PERMISSIONS.WRITE_EXTERNAL_STORAGE, { 'title': 'ReactNativeCode Storage Permission', 'message': 'ReactNativeCode App needs access to your storage to download Photos.' } ) if (granted === PermissionsAndroid.RESULTS.GRANTED) { Alert.alert("Storage Permission Granted."); } else { Alert.alert("Storage Permission Not Granted"); } } catch (err) { console.warn(err) } } export default class MainActivity extends Component { async componentDidMount() { await request_storage_runtime_permission() } downloadImage = () => { var date = new Date(); var image_URL = 'https://reactnativecode.com/wp-content/uploads/2018/02/motorcycle.jpg'; var ext = this.getExtention(image_URL); ext = "." + ext[0]; const { config, fs } = RNFetchBlob; let PictureDir = fs.dirs.PictureDir let options = { fileCache: true, addAndroidDownloads: { useDownloadManager: true, notification: true, path: PictureDir + "/image_" + Math.floor(date.getTime() + date.getSeconds() / 2) + ext, description: 'Image' } } config(options).fetch('GET', image_URL).then((res) => { Alert.alert("Image Downloaded Successfully."); }); } getExtention = (filename) => { return (/[.]/.exec(filename)) ? /[^.]+$/.exec(filename) : undefined; } render() { return ( <View style={styles.MainContainer}> <Image source={{ uri: 'https://reactnativecode.com/wp-content/uploads/2018/02/motorcycle.jpg' }} style={{ width: 300, height: 300, resizeMode: 'contain', margin: 5 }} /> <TouchableOpacity style={styles.button} onPress={this.downloadImage} > <Text style={styles.text}>Click Here To Download Above Image</Text> </TouchableOpacity> </View> ); } } const styles = StyleSheet.create({ MainContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', }, button: { width: '80%', paddingTop: 3, paddingBottom: 3, backgroundColor: '#2E7D32', borderRadius: 7, margin: 10 }, text: { color: '#fff', fontSize: 20, textAlign: 'center', padding: 5 } }); |
Screenshots:
Thank You sir
Welcome Pardeep 🙂 .
How about ios? I try it but image not downloaded
Bryan there is some changes in iOS devices, I am working on it & publish new tutorial regarding iOS download.
How about using CameraRoll api from RN itself? It can save the image to iPhone gallery
Bryan i have note used the Camera roll API if you do know about it then share the code here in comment section.
How to create folder
how to create folder in PictureDir
hii sir how to download image in ios i try but image not show in device
const { dirs: { DownloadDir, DocumentDir } } = RNFetchBlob.fs;
const isIOS = Platform.OS === ‘ios’;
const aPath = Platform.select({ ios: DownloadDir, android: DownloadDir });
const fPath =
${aPath}/${this.state.file_ex}
;const configOptions = Platform.select({
ios: {
fileCache: true,
path: fPath,
// appendExt: ‘pdf’,
},
if (isIOS) { // This iOS block works fine..
RNFetchBlob.config(configOptions)
.fetch(‘GET’, image_URL)
.then(async (resp) => {
console.log(“file “,resp)
// This options is for file sharing in iOS. Works fine.
const options = {
title: ‘Receipt File’, // type: ‘pdf’,
urls: [
file://${fPath}
],};
console.log(options)
// await Share.open(options);
// await RNFS.unlink(fPath);
});
return;
}
i got this resp
data: “/var/mobile/Containers/Data/Application/90BC2373-1486-4D67-84D4-3DCD47A0E428/Downloads/doc_73.JPG”
taskId: “6598unz555rzlmq219p229”
type: “path”
bro some time the image download is not working.any idea
its take to much time to download any ideas