Upload Picture From Camera Roll to S3 React Native Expo
Mega Parcel Sale is ON! Get ALL of our React Native codebases at 80% OFF discount 🔥
In this tutorial we will build a React Native app that allows users to upload images and videos from their camera and photo library straight into a AWS S3 bucket. As AWS is the leader of deject providers, a huge role of the React Native ecosystem is using AWS as the backend for their app. With the release of AWS Amplify, using AWS as backend for a React Native app has never been easier to implement.
The app we are going to build in this React Native AWS tutorial will upload and store prototype and video files using Amazon S3 bucket. In this commodity, we will teach you how epitome and video storage works in React Native using AWS S3 saucepan. Every single stride of the implementation volition be detailed and no stones volition exist left unturned. Then allow united states of america get into it.
For those who are not familiar with AWS S3 buckets already, here'south is the formal definition of Amazon S3 and what a bucket is:
Amazon S3 stores data equally objects within buckets . An object consists of a file and optionally any metadata that describes that file. To shop an object in Amazon S3, you upload the file you lot want to store to a bucket. When you upload a file, y'all can set up permissions on the object and any metadata.
1. Creating the React Native Project
Open a new Terminal instance, and run the post-obit
react-native init s3bucket_storage_example
Then we install and configure the required dependencies, using yarn:
yarn add react-native-image-picker react-native-video @react-native-community/netinfo @react-native-async-storage/async-storage
or using npm:
npm install react-native-prototype-picker react-native-video @react-native-community/netinfo @react-native-async-storage/async-storage -S
For iOS you as well need to install the pods by running
cd ios && pod install
Then add the following snippet to your ios/<projectName>/Info.plist
to request Photograph Library permissions.
<key>NSPhotoLibraryUsageDescription</primal> <string>$(PRODUCT_NAME) would like access to your photo gallery.</string>
two. Picking Photos & Videos from Photo Library
Our first task here is to fetch an prototype or video from the user'south photo library. In social club to achieve that, we are going to leveragereact-native-image-picker
to pick media files from the library. To be able to display and play videos, we are also going to employ the npm bundlereact-native-video
. Now, allow's replace all yourApp.js file with the following source code:
import React, {useState} from 'react'; import { View, Text, TouchableOpacity, StyleSheet, Alert, Image, } from 'react-native'; import {launchImageLibrary} from 'react-native-image-picker'; import Video from 'react-native-video'; role S3StorageUpload() { const [asset, setAsset] = useState(null); const selectFile = async () => { await launchImageLibrary({mediaType: 'mixed'}, result => { if (!result.avails) { Alert.alert(effect.errorMessage); return; } setAsset(upshot.assets[0]); }); }; return ( <View way={styles.container}> <TouchableOpacity onPress={selectFile}> <Text style={styles.button}>SELECT {nugget ? 'Some other' : ''} FILE</Text> </TouchableOpacity> {asset ? ( asset.type.split('/')[0] === 'image' ? ( <Paradigm fashion={styles.selectedImage} source={{uri: asset?.uri ?? ''}} /> ) : ( <Video fashion={styles.selectedImage} source={{uri: asset?.uri ?? ''}} /> ) ) : goose egg} {asset && ( <> <TouchableOpacity onPress={() => setAsset(null)}> <Text style={styles.cancelButton}>Remove Selected Paradigm</Text> </TouchableOpacity> </> )} </View> ); } const styles = StyleSheet.create({ button: { fontSize: xx, color: '#fff', backgroundColor: 'bluish', paddingVertical: 20, paddingHorizontal: 30, marginHorizontal: 20, marginVertical: x, textAlign: 'center', fontWeight: 'bold', }, cancelButton: { backgroundColor: '#fff', color: 'blue', }, selectedImage: { width: 175, superlative: 200, marginTop: 20, }, container: { flex: 1, justifyContent: 'center', alignItems: 'middle', }, }); export default S3StorageUpload;
Now, run your mobile app in your device, simulator or emulator. Y'all will notice that you now are able to pick a photo or a video from your photo library.
3. AWS Dilate Setup
Now that our mobile application UI is pretty much implemented, let'southward focus on how to set up the actual backend storage, and how we tin can integrate the mobile React Native app to communicate with the AWS backend, securely and effectively.
a. Create A New AWS Dilate Projection
Head over to the AWS website and create a new AWS Dilate projection.
b. Install the AWS Amplify CLI
Next, nosotros demand to install AWS Dilate CLI on our local car past running the following command on your terminal.
npm install -1000 @aws-amplify/cli
This AWS Amplify CLI will enable us run AWS commands anywhere on our local car. For instance, nosotros can update our local AWS configuration by pulling our AWS backend and updating our backend past pushing local configuration changes to the backend.
c. Pull The AWS Amplify Project into the React Native Codebase
Pull your already created Amplify backend project into your React Native project by running the following command at the root of your React Native project:
dilate pull --appId <appID> --envName <appName>
Note: Please be sure to verify the app login on your Dilate UI Admin, then select your preferred editor, blazon of app as Javascript
, and framework every bit React Native
. You need to enter Y when asked if yous wish to alter the backend. Default entries should be immune for the remaining prompts.
c. Enable Storage in the AWS Dilate Project
At the root of your React Native project run amplify add storage
to add together storage to your backend project equally seen in the below screenshot. After that is done yous should push button your new project configurations to the backend by running amplify push
.
Note: On prompted you should select Content (Images, sound, video, etc.)
. Adding hallmark or functions to your project is not mandatory and every other options can be left as their default value.
3. Upload Photos & Videos to AWS S3 Bucket in React Native
We've finally reached the core function of this tutorial. Then far, we fix the React Native project, the AWS backend project, and we built the integration between these 2. We've also implemented the ability for the users to option photos from the gallery, so all we demand to exercise at present is get those photos and transport them over to the S3 cloud.
a. Install aws-amplify
Into the React Native Projection
yarn add together aws-amplify
or
npm install aws-amplify -S
b. And so Import AWS Dilate into Your App.js
import Amplify, {Storage} from 'aws-amplify';
and configure your AWS Dilate:
import awsconfig from './src/aws-exports'; Amplify.configure(awsconfig);
c. Add together the following two states to the S3StorageUpload
const [progressText, setProgressText] = useState(''); const [isLoading, setisLoading] = useState(false);
progressText
will be used to display the progress of the upload and isLoading
to assist disable our buttons from performing whatsoever action while the prototype is getting uploaded.
d. Add the following handler and helper functions
First we have to catechumen our URI
to a hulkusing fetchResourceFromURI
then uploadResource
uploads the file using the asset URI as the cardinal.A success callback is passed to recall the key of the uploaded file and this key is of import considering you need it to get the URI of the resource URI from the backend.
const fetchResourceFromURI = async uri => { const response = await fetch(uri); console.log(response); const blob = await response.blob(); return hulk; }; const uploadResource = async () => { if (isLoading) return; setisLoading(truthful); const img = await fetchResourceFromURI(asset.uri); return Storage.put(asset.uri, img, { level: 'public', contentType: nugget.blazon, progressCallback(uploadProgress) { setProgressText( `Progress: ${Math.round( (uploadProgress.loaded / uploadProgress.total) * 100, )} %`, ); panel.log( `Progress: ${uploadProgress.loaded}/${uploadProgress.total}`, ); }, }) .then(res => { setProgressText('Upload Done: 100%'); setAsset(null); setisLoading(false); Storage.get(res.fundamental) .and then(result => panel.log(consequence)) .grab(err => { setProgressText('Upload Error'); console.log(err); }); }) .catch(err => { setisLoading(imitation); setProgressText('Upload Error'); console.log(err); }); };
4. Trigger the File Upload to AWS S3 in React Native
return ( <View style={styles.container}> <TouchableOpacity onPress={selectFile}> <Text style={styles.button}>SELECT {asset ? 'Another' : ''} FILE</Text> </TouchableOpacity> {asset ? ( asset.blazon.split('/')[0] === 'image' ? ( <Epitome style={styles.selectedImage} source={{uri: asset?.uri ?? ''}} /> ) : ( <Video style={styles.selectedImage} source={{uri: nugget?.uri ?? ''}} /> ) ) : zippo} {asset && ( <> <TouchableOpacity onPress={uploadResource}> <Text style={styles.push}>UPLOAD</Text> </TouchableOpacity> <TouchableOpacity onPress={() => setAsset(naught)}> <Text style={styles.cancelButton}>Remove Selected Image</Text> </TouchableOpacity> </> )} <Text>{progressText}</Text> </View> );
In the above snippet nosotros edit and update the UI by adding a push to trigger the uploadResource
part. Here'south a snippet brusque clip showing how this works.
5. Deleting a File from AWS S3 Bucket in React Native
Deleting a file is straightforward and tin be done by a single role telephone call that takes the file keyequally a required parameters and an optional parameter protectedLevel that specifies the File Access Level of the file when it was uploaded
expect Storage.remove('img.png');
vi. File Access Levels in AWS
There are iii File Access Levels namely: public
, protected
, individual
. The default level is public
for example when uploading a file using Storage.go('video.mp4')
unless configured otherwise as follows:
Storage.configure({ level: 'individual' });
According to the official documentation:
-
Public: Accessible by all users of your app. Files are stored under the
public/
path in your S3 bucket. -
Protected: Readable by all users, but writable only by the creating user. Files are stored under
protected/{user_identity_id}/
where theuser_identity_id
corresponds to the unique Amazon Cognito Identity ID for that user. -
Private: But accessible for the individual user. Files are stored under
private/{user_identity_id}/
where theuser_identity_id
corresponds to the unique Amazon Cognito Identity ID for that user.
Note
You may get the post-obit mistake when you run your app:Error: jest-haste-map: Haste module naming collison
:
To fix this issue, but delete theamplify/#current-deject-backend
folder and re-build the app.
Conclusion
In this tutorial, we accept successfully been able to set up an AWS Amplify storage project in your AWS Dilate account, and so we configured it on your local machine and integrated it with the React Native project. Implementation wise, we built a feature that allows the users to pick photos and videos from their photo gallery and upload it to the S3 bucket deject. Nosotros've likewise learned how to remove those files from the cloud, and as well, we got familiar with the various privacy levels for the AWS file cloud.
If yous want to skip the tutorial, and spring straight into the lawmaking, you can find the Github React Native AWS S3 Saucepan projection here. If y'all found this helpful, please give us a star on Github and share this article with your customs / your audience.
Source: https://instamobile.io/react-native-tutorials/react-native-aws-s3/