Image uploading is one of the most usable functionality in react native development area because in today scenario every android and iOS application is fully dynamic and comes with Login functionality where user can set his own image as profile picture or upload images from his application. So in this tutorial we would going to create a react native application to Upload Image to Server using PHP MySQL and Store Image URL in Database so it can be accessible for further use from directly server.
What we are doing in this project : We would store the image into a folder created in our hosting server root directory and after successfully done the uploading process we would store the complete image URL(Path of Server) into MySQL database using PHP scripting language after that we would show a response message to user in react native application.
List of React Native libraries used in this project :
- react-native-image-picker : To pick image form gallery or camera.
- rn-fetch-blob : Send selected image to server.
Contents in this project React Native Upload Image to Server using PHP MySQL-Store Image URL in Database iOS Android Example Tutorial:
1. Installing the react-native-image-picker library :
1. Before getting started we need to install the react-native-image-picker library in our current project. To install the react-native-image-picker library you need to open your react native project folder in Command Prompt or Terminal and execute below command .
1
|
npm install react–native–image–picker@latest —save
|
2. After executing the above command it will start downloading and installing the react-native-image-picker library. Below is the screenshot of CMD after successfully install the library.
3. After installing the library we need to execute the
react–native link command , This command will refresh and re-index the complete react native project folder and index the react native image picker library in your current project.
4. Configure Project for Android devices :
1. Open build.gradle file present in your folder located in YourReactNativeProject/android.
2. Replace classpath ‘com.android.tools.build:gradle:2.2.+’ on previous line.
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
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath ‘com.android.tools.build:gradle:2.2.+’
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
mavenLocal()
jcenter()
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url “$rootDir/../node_modules/react-native/android”
}
}
}
|
3. Now open YourReactNativeProjectFolder/android/gradle/wrapper/gradle-wrapper.properties file and replace previous distributionUrl line to this distributionUrl=https://services.gradle.org/distributions/gradle-2.14.1-all.zip .Below is the complete source code of gradle-wrapper.properties file.
1
2
3
4
5
|
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https://services.gradle.org/distributions/gradle-2.14.1-all.zip
|
4. Finally Open AndroidManifest.xml file present inside YourReactNativeProjectFolderandroidappsrcmain and Add CAMERA permission and WRITE_EXTERNAL_STORAGE permission. Below is the final code of AndroidManifest.xml 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
|
<manifest xmlns:android=“http://schemas.android.com/apk/res/android”
package=“com.imagepickerproject”
android:versionCode=“1”
android:versionName=“1.0”>
<uses–permission android:name=“android.permission.INTERNET” />
<uses–permission android:name=“android.permission.SYSTEM_ALERT_WINDOW”/>
<uses–permission android:name=“android.permission.CAMERA” />
<uses–permission android:name=“android.permission.WRITE_EXTERNAL_STORAGE”/>
<uses–sdk
android:minSdkVersion=“16”
android:targetSdkVersion=“22” />
<application
android:name=“.MainApplication”
android:allowBackup=“true”
android:label=“@string/app_name”
android:icon=“@mipmap/ic_launcher”
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” />
</intent–filter>
</activity>
<activity android:name=“com.facebook.react.devsupport.DevSettingsActivity” />
</application>
</manifest>
|
5. Configure Project for iOS devices :
1. Open YourReactNativeProject -> ios – > YourProjectName.xcodeproj file.
2. Now we need to open info.plist file from side panel, This file contain all the useful information about your project.
3. Click on the Small + Plus icon present on the top.
4. Select the Privacy – Camera Usages Description permission like i did in below screenshot.
5. Select Privacy – Photo Library Usages permission .
6. Now we need to enter some info text in front of both permissions like i did in below screenshot so we remember what is the purpose of this permission.
2. Installing the rn-fetch-blob library :
1. Open your react native project folder in CMD and execute below command like i did in below screenshot.
1
|
npm install —save rn–fetch–blob
|
2. After successfully install the library we need to execute
react–native link command in order to refresh our complete project and index the react native fetch blob library.
3. Creating MySQL database+Table on your PhpMyAdmin Server :
1. Create a new database in your PHPMYADMIN control panel named as mydatabase .
2. Inside this database we need to make a table named as image_upload_table with 3 columns id, image_tag and image_path. See the below MySQL table screenshot to know how to set their values. This table is used to store the complete image URL with domain name and a image tag.
4. Creating PHP Script to receive and store send image on Server and Insert image URL in MySQL database:
I have created a folder name as Project and inside the folder i have created another folder name as Uploads . So all the images will upload inside the Uploads folder.
Code for upload_image.php 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
|
<?php
//Define your host here.
$hostname = “localhost”;
//Define your database User Name here.
$username = “root”;
//Define your database Password here.
$password = “”;
//Define your Database Name here.
$dbname = “mydatabase”;
$conn = mysql_connect($hostname, $username, $password);
mysql_select_db($dbname, $conn);
// Type your website name or domain name here.
$domain_name = “http://192.168.2.102/Project/” ;
// Image uploading folder.
$target_dir = “uploads”;
// Generating random image name each time so image name will not be same .
$target_dir = $target_dir . “/” .rand() . “_” . time() . “.jpeg”;
// Receiving image tag sent from application.
$img_tag = $_POST[“image_tag”];
// Receiving image sent from Application
if(move_uploaded_file($_FILES[‘image’][‘tmp_name’], $target_dir)){
// Adding domain name with image random name.
$target_dir = $domain_name . $target_dir ;
// Inserting data into MySQL database.
mysql_query(“insert into image_upload_table ( image_tag, image_path) VALUES(‘$img_tag’ , ‘$target_dir’)”);
$MESSAGE = “Image Uploaded Successfully.” ;
// Printing response message on screen after successfully inserting the image .
echo json_encode($MESSAGE);
}
?>
|
5. Start Coding of React Native :
1. Open your project’s App.js file.
2. Import StyleSheet, Text, View, PixelRatio, TouchableOpacity, Image, TextInput and Alert component in your project.
1
2
3
|
import React, { Component } from ‘react’;
import { StyleSheet, Text, View, PixelRatio, TouchableOpacity, Image, TextInput, Alert } from ‘react-native’;
|
3. Import ImagePicker and RNFetchBlob module from react-native-image-picker and rn-fetch-blob library .
1
2
3
|
import ImagePicker from ‘react-native-image-picker’;
import RNFetchBlob from ‘rn-fetch-blob’;
|
4. Create a class named as Project in your App.js file.
1
2
3
4
5
6
|
export default class Project extends Component {
}
|
5. Create constructor() in your project folder with 3 States named as ImageSource, data and Image_TAG.
ImageSource : Used to hold the image path when we select image from gallery or capture image form camera.
data : Used to hold the selected image as object to send on sever.
Image_TAG : Used to hold the image tag, some text send with image.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
constructor() {
super();
this.state = {
ImageSource: null,
data: null,
Image_TAG: ”
}
}
|
6. Create two functions named as selectPhotoTapped and ImagePicker.showImagePicker , these both functions is predefined inbuilt functions of react native image picker library.
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
|
selectPhotoTapped() {
const options = {
quality: 1.0,
maxWidth: 500,
maxHeight: 500,
storageOptions: {
skipBackup: true
}
};
ImagePicker.showImagePicker(options, (response) => {
console.log(‘Response = ‘, response);
if (response.didCancel) {
console.log(‘User cancelled photo picker’);
}
else if (response.error) {
console.log(‘ImagePicker Error: ‘, response.error);
}
else if (response.customButton) {
console.log(‘User tapped custom button: ‘, response.customButton);
}
else {
let source = { uri: response.uri };
this.setState({
ImageSource: source,
data: response.data
});
}
});
}
|
7. Create another function named as uploadImageToServer(). Inside this function we would simply use the RNFetchBlob.fetch() method to upload the selected image on our server. We are testing this application on our localhost so i am putting my IP address here.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
uploadImageToServer = () => {
RNFetchBlob.fetch(‘POST’, ‘http://192.168.2.102/Project/upload_image.php’, {
Authorization: “Bearer access-token”,
otherHeader: “foo”,
‘Content-Type’: ‘multipart/form-data’,
}, [
{ name: ‘image’, filename: ‘image.png’, type: ‘image/png’, data: this.state.data },
{ name: ‘image_tag’, data: this.state.Image_TAG }
]).then((resp) => {
var tempMSG = resp.data;
tempMSG = tempMSG.replace(/^“|”$/g, ”);
Alert.alert(tempMSG);
}).catch((err) => {
// …
})
}
|
8. Create 2 Touchable opacity component and 1 Text Input component inside render’s return block .
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
|
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={this.selectPhotoTapped.bind(this)}>
<View style={styles.ImageContainer}>
{this.state.ImageSource === null ? <Text>Select a Photo</Text> :
<Image style={styles.ImageContainer} source={this.state.ImageSource} />
}
</View>
</TouchableOpacity>
<TextInput
placeholder=“Enter Image Name “
onChangeText={data => this.setState({ Image_TAG: data })}
underlineColorAndroid=‘transparent’
style={styles.TextInputStyle}
/>
<TouchableOpacity onPress={this.uploadImageToServer} activeOpacity={0.6} style={styles.button} >
<Text style={styles.TextStyle}> UPLOAD IMAGE TO SERVER </Text>
</TouchableOpacity>
</View>
);
}
|
9. 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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: ‘center’,
backgroundColor: ‘#FFF8E1’,
paddingTop: 20
},
ImageContainer: {
borderRadius: 10,
width: 250,
height: 250,
borderColor: ‘#9B9B9B’,
borderWidth: 1 / PixelRatio.get(),
justifyContent: ‘center’,
alignItems: ‘center’,
backgroundColor: ‘#CDDC39’,
},
TextInputStyle: {
textAlign: ‘center’,
height: 40,
width: ‘80%’,
borderRadius: 10,
borderWidth: 1,
borderColor: ‘#028b53’,
marginTop: 20
},
button: {
width: ‘80%’,
backgroundColor: ‘#00BCD4’,
borderRadius: 7,
marginTop: 20
},
TextStyle: {
color: ‘#fff’,
textAlign: ‘center’,
padding: 10
}
});
|
10. 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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
import React, { Component } from ‘react’;
import { StyleSheet, Text, View, PixelRatio, TouchableOpacity, Image, TextInput, Alert } from ‘react-native’;
import ImagePicker from ‘react-native-image-picker’;
import RNFetchBlob from ‘rn-fetch-blob’;
export default class Project extends Component {
constructor() {
super();
this.state = {
ImageSource: null,
data: null,
Image_TAG: ”
}
}
selectPhotoTapped() {
const options = {
quality: 1.0,
maxWidth: 500,
maxHeight: 500,
storageOptions: {
skipBackup: true
}
};
ImagePicker.showImagePicker(options, (response) => {
console.log(‘Response = ‘, response);
if (response.didCancel) {
console.log(‘User cancelled photo picker’);
}
else if (response.error) {
console.log(‘ImagePicker Error: ‘, response.error);
}
else if (response.customButton) {
console.log(‘User tapped custom button: ‘, response.customButton);
}
else {
let source = { uri: response.uri };
this.setState({
ImageSource: source,
data: response.data
});
}
});
}
uploadImageToServer = () => {
RNFetchBlob.fetch(‘POST’, ‘http://192.168.2.102/Project/upload_image.php’, {
Authorization: “Bearer access-token”,
otherHeader: “foo”,
‘Content-Type’: ‘multipart/form-data’,
}, [
{ name: ‘image’, filename: ‘image.png’, type: ‘image/png’, data: this.state.data },
{ name: ‘image_tag’, data: this.state.Image_TAG }
]).then((resp) => {
var tempMSG = resp.data;
tempMSG = tempMSG.replace(/^“|”$/g, ”);
Alert.alert(tempMSG);
}).catch((err) => {
// …
})
}
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={this.selectPhotoTapped.bind(this)}>
<View style={styles.ImageContainer}>
{this.state.ImageSource === null ? <Text>Select a Photo</Text> :
<Image style={styles.ImageContainer} source={this.state.ImageSource} />
}
</View>
</TouchableOpacity>
<TextInput
placeholder=“Enter Image Name “
onChangeText={data => this.setState({ Image_TAG: data })}
underlineColorAndroid=‘transparent’
style={styles.TextInputStyle}
/>
<TouchableOpacity onPress={this.uploadImageToServer} activeOpacity={0.6} style={styles.button} >
<Text style={styles.TextStyle}> UPLOAD IMAGE TO SERVER </Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: ‘center’,
backgroundColor: ‘#FFF8E1’,
paddingTop: 20
},
ImageContainer: {
borderRadius: 10,
width: 250,
height: 250,
borderColor: ‘#9B9B9B’,
borderWidth: 1 / PixelRatio.get(),
justifyContent: ‘center’,
alignItems: ‘center’,
backgroundColor: ‘#CDDC39’,
},
TextInputStyle: {
textAlign: ‘center’,
height: 40,
width: ‘80%’,
borderRadius: 10,
borderWidth: 1,
borderColor: ‘#028b53’,
marginTop: 20
},
button: {
width: ‘80%’,
backgroundColor: ‘#00BCD4’,
borderRadius: 7,
marginTop: 20
},
TextStyle: {
color: ‘#fff’,
textAlign: ‘center’,
padding: 10
}
});
|
Screenshots: