Uploading File in React Native
In this post, I’ll show you how to Upload File/Image to Server with Form Data in React Native. This example will cover how to pick any file from the file system and upload it to the server. I have also shared the server-side PHP code with the React Native File upload example.
If you noticed the title we are going to use FormData to upload the File on the server because I personally do not like to add third-party dependencies in my projects as long as using those dependencies is the last option.
Why I use FormData for File Uploading in React Native?
If you search for the file uploading examples in React Native over the internet you will find many examples and most of them have used external third party dependencies to upload the file on the server, but I personally try to avoid the third-party dependencies and like to find the other solution and FormData is one of them. The reason for avoiding third-party dependencies and using FormData is
- Third-party dependencies can make your project bulky
- Managing the proper version of dependencies
- After the major update of the dependencies, you need to update the project as well
- It is very tough to update others code in case of small update required
- The special thing about FormData is that network methods, such as fetch, can accept a FormData object as a body. It is encoded and sent out with Content-Type: multipart/form-data.
These are the primary reasons for which I use FormData for File Uploading.
How to use FormData for File Uploading in React Native?
Uploading a file using FormDate is very simple. It is divided into 3 steps:
- Pick a file using any file picker. Here I am using react-native-document-picker for file picking
const res = await DocumentPicker.pick({ type: [DocumentPicker.types.allFiles], }); this.setState({ singleFile: res });
- Create FormData by creating an object and appending the values you want to send to the server
const data = new FormData(); data.append('name', 'Image Upload'); data.append('file_attachment', fileToUpload);
- Using fetch method calling a file upload web service which will send the created FormData as a multipart/form-data to upload the file
let uploadImage = async () => { //Check if any file is selected or not if (singleFile != null) { //If file selected then create FormData const fileToUpload = singleFile; const data = new FormData(); data.append('name', 'Image Upload'); data.append('file_attachment', fileToUpload); let res = await fetch( 'http://localhost//webservice/user/uploadImage', { method: 'post', body: data, headers: { 'Content-Type': 'multipart/form-data; ', }, } ); let responseJson = await res.json(); if (responseJson.status == 1) { alert('Upload Successful'); } } else { //if no file selected the show alert alert('Please Select File first'); } };
What We are Going to Create in Uploading File Example?
In this example, We are going to create one Screen with two buttons. One button to pick the file from the file system and another button to upload the file on the server.
If you face any challenge with the file picker then you can see Example of File Picker in React Native it will help you to solve your problems. Now let’s get started with the Example.
To Make a React Native App
Getting started with React Native will help you to know more about the way you can make a React Native project. We are going to use react native command line interface to make our React Native App.
If you have previously installed a global react-native-cli package, please remove it as it may cause unexpected issues:
npm uninstall -g react-native-cli @react-native-community/cli
Run the following commands to create a new React Native project
npx react-native init ProjectName
If you want to start a new project with a specific React Native version, you can use the --version argument:
npx react-native init ProjectName --version X.XX.X
Note If the above command is failing, you may have old version of react-native
or react-native-cli
installed globally on your pc. Try uninstalling the cli and run the cli using npx.
This will make a project structure with an index file named App.js in your project directory.
Installation of Dependency
As I mentioned, to pick a file we are going to use react-native-document-picker
which provides DocumentPicker
component. To use react-native-document-picker
we need to install it using the following commands
Open the terminal and jump into your project
cd ProjectName
Run the following command
npm install react-native-document-picker --save
Linking of Dependency
After the updation of React Native 0.60, they have introduced autolinking feature means we do not require to link the library but they have also mentioned that some libraries need linking and react-native-document-picker is one of those cases. So for that, we need to link the library using
react-native link react-native-document-picker
CocoaPods Installation
Now we need to install pods
cd ios && pod install && cd ..
Code for the File Upload in React Native
Open App.js in any code editor and replace the code with the following code
App.js
// Example to Pick and Upload files in React Native
// https://aboutreact.com/file-uploading-in-react-native/
// Import React
import React, { useState } from 'react';
// Import core components
import {
StyleSheet,
Text,
View,
TouchableOpacity
} from 'react-native';
// Import Document Picker
import DocumentPicker from 'react-native-document-picker';
const App = () => {
const [singleFile, setSingleFile] = useState(null);
const uploadImage = async () => {
// Check if any file is selected or not
if (singleFile != null) {
// If file selected then create FormData
const fileToUpload = singleFile;
const data = new FormData();
data.append('name', 'Image Upload');
data.append('file_attachment', fileToUpload);
// Please change file upload URL
let res = await fetch(
'http://localhost/upload.php',
{
method: 'post',
body: data,
headers: {
'Content-Type': 'multipart/form-data; ',
},
}
);
let responseJson = await res.json();
if (responseJson.status == 1) {
alert('Upload Successful');
}
} else {
// If no file selected the show alert
alert('Please Select File first');
}
};
const selectFile = async () => {
// Opening Document Picker to select one file
try {
const res = await DocumentPicker.pick({
// Provide which type of file you want user to pick
type: [DocumentPicker.types.allFiles],
// There can me more options as well
// DocumentPicker.types.allFiles
// DocumentPicker.types.images
// DocumentPicker.types.plainText
// DocumentPicker.types.audio
// DocumentPicker.types.pdf
});
// Printing the log realted to the file
console.log('res : ' + JSON.stringify(res));
// Setting the state to show single file attributes
setSingleFile(res);
} catch (err) {
setSingleFile(null);
// Handling any exception (If any)
if (DocumentPicker.isCancel(err)) {
// If user canceled the document selection
alert('Canceled');
} else {
// For Unknown Error
alert('Unknown Error: ' + JSON.stringify(err));
throw err;
}
}
};
return (
<View style={styles.mainBody}>
<View style={{ alignItems: 'center' }}>
<Text style={{ fontSize: 30, textAlign: 'center' }}>
React Native File Upload Example
</Text>
<Text
style={{
fontSize: 25,
marginTop: 20,
marginBottom: 30,
textAlign: 'center',
}}>
www.aboutreact.com
</Text>
</View>
{/*Showing the data of selected Single file*/}
{singleFile != null ? (
<Text style={styles.textStyle}>
File Name: {singleFile.name ? singleFile.name : ''}
{'\n'}
Type: {singleFile.type ? singleFile.type : ''}
{'\n'}
File Size: {singleFile.size ? singleFile.size : ''}
{'\n'}
URI: {singleFile.uri ? singleFile.uri : ''}
{'\n'}
</Text>
) : null}
<TouchableOpacity
style={styles.buttonStyle}
activeOpacity={0.5}
onPress={selectFile}>
<Text style={styles.buttonTextStyle}>Select File</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.buttonStyle}
activeOpacity={0.5}
onPress={uploadImage}>
<Text style={styles.buttonTextStyle}>Upload File</Text>
</TouchableOpacity>
</View>
);
};
const styles = StyleSheet.create({
mainBody: {
flex: 1,
justifyContent: 'center',
padding: 20,
},
buttonStyle: {
backgroundColor: '#307ecc',
borderWidth: 0,
color: '#FFFFFF',
borderColor: '#307ecc',
height: 40,
alignItems: 'center',
borderRadius: 30,
marginLeft: 35,
marginRight: 35,
marginTop: 15,
},
buttonTextStyle: {
color: '#FFFFFF',
paddingVertical: 10,
fontSize: 16,
},
textStyle: {
backgroundColor: '#fff',
fontSize: 15,
marginTop: 16,
marginLeft: 35,
marginRight: 35,
textAlign: 'center',
},
});
export default App;
Server Side PHP Code
Please find the server-side PHP code below. You will need to set up a local server to use this Script.
Core PHP Code (upload.php)
<?php
if(!empty($_FILES['file_attachment']['name']))
{
$target_dir = "uploads/";
if (!file_exists($target_dir))
{
mkdir($target_dir, 0777);
}
$target_file =
$target_dir . basename($_FILES["file_attachment"]["name"]);
$imageFileType =
strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
// Check if file already exists
if (file_exists($target_file)) {
echo json_encode(
array(
"status" => 0,
"data" => array()
,"msg" => "Sorry, file already exists."
)
);
die();
}
// Check file size
if ($_FILES["file_attachment"]["size"] > 50000000) {
echo json_encode(
array(
"status" => 0,
"data" => array(),
"msg" => "Sorry, your file is too large."
)
);
die();
}
if (
move_uploaded_file(
$_FILES["file_attachment"]["tmp_name"], $target_file
)
) {
echo json_encode(
array(
"status" => 1,
"data" => array(),
"msg" => "The file " .
basename( $_FILES["file_attachment"]["name"]) .
" has been uploaded."));
} else {
echo json_encode(
array(
"status" => 0,
"data" => array(),
"msg" => "Sorry, there was an error uploading your file."
)
);
}
}
?>
PHP CodeIgniter Code
/* Update Images*/
public function uploadImage() {
if(!empty($_FILES['file_attachment']['name'])) {
$res = array();
$name = 'file_attachment';
$imagePath = 'assets/upload/file_attachment';
$temp = explode(".",$_FILES['file_attachment']['name']);
$extension = end($temp);
$filenew = str_replace(
$_FILES['file_attachment']['name'],
$name,
$_FILES['file_attachment']['name']) .
'_' . time() . '' . "." . $extension;
$config['file_name'] = $filenew;
$config['upload_path'] = $imagePath;
$this->upload->initialize($config);
$this->upload->set_allowed_types('*');
$this->upload->set_filename($config['upload_path'],$filenew);
if(!$this->upload->do_upload('file_attachment')) {
$data = array('msg' => $this->upload->display_errors());
} else {
$data = $this->upload->data();
if(!empty($data['file_name'])){
$res['image_url'] = 'assets/upload/file_attachment/' .
$data['file_name'];
}
if (!empty($res)) {
echo json_encode(
array(
"status" => 1,
"data" => array(),
"msg" => "upload successfully",
"base_url" => base_url(),
"count" => "0"
)
);
}else{
echo json_encode(
array(
"status" => 1,
"data" => array(),
"msg" => "not found",
"base_url" => base_url(),
"count" => "0"
)
);
}
}
}
}
To Run the React Native App
Open the terminal again and jump into your project using.
cd ProjectName
1. Start Metro Bundler
First, you will need to start Metro, the JavaScript bundler that ships with React Native. To start Metro bundler run following command
npx react-native start
Once you start Metro Bundler it will run forever on your terminal until you close it. Let Metro Bundler run in its own terminal. Open a new terminal and run the application.
2. Start React Native Application
To run the project on an Android Virtual Device or on real debugging device
npx react-native run-android
or on the iOS Simulator by running (macOS only)
npx react-native run-ios
Output Screenshots
This is how you can upload File/Image to Server with Form Data in React Native. If you have any doubts or you want to share something about the topic you can comment below or contact us here. There will be more posts coming soon. Stay tuned!
Hope you liked it. 🙂
For this example you have to setup your own server or have to get the API to upload the file and have to replace http://localhost/upload.php with your upload API.
Here I have shared the server side code just to have an idea what I have done at server side.
Hi,
i have a problem:
the procedure is all right but on, file .php create folder but NOT upload image!
You can help me
Great example, but please don’t use 777 for the uploads folder… 755 is more secure
facing problem with expo
getting ‘unknown error’
exactly to following posting
https://github.com/rnmods/react-native-document-picker/issues/234
Will this work with Expo ?