How to Upload Images in S3 Bucket Using React

Cover image for Adding image upload to a React Native app with AWS Amplify

AWS profile image Derek Bingham ☘️

Adding epitome upload to a React Native app with AWS Amplify

Intro

In this blog post I volition detail how to leverage AWS Amplify, AWS Appsync and Amazon S3 to provide an image upload capability into a react native app.

This blog assumes that the reader is familiar with AWS Amplify and its characteristic categories, however if y'all are not familiar then please have a read of this great intro by @ajonp one of our AWS community members.

I will also be working off an existing AWS backend awarding that has already been created with the AWS Amplify CLI and has had both the 'auth' and 'api' characteristic categories added. You tin follow along with this cosmos by going to the official Amplify react-native docs. Or ;tldr it and simply clone this repo

Notation - if you do end up cloning the repo, remember to run 'amplify configure' and 'amplify init' to re-configure the project to a new cloud back cease in your own AWS account.

What are nosotros building ?

The base application nosotros will be adding photo/image storage to should look something like the below image.

Alt Text

There are 2 views in this app

  • A list of Todo's that have already been created.
  • A form to create a new Todo

Clicking on 'New To Do' button on the 'list view' will bring you to the 'create view' and once a new todo has been created the app will navigate back to the 'list view' from the 'create view'

So, aught besides catchy here, what nosotros are going to add to this app is the ability to save images to our cloud backend when in the 'create view' and the ability to see those images in the 'listing view'.

Adding the image concept to backend resource.

Offset thing is confirming what dilate characteristic categories we have installed - to notice this out we simply run the dilate condition command which gives the following output
Amplify status

Equally you can see, we have both auth and api feature categories installed - so that ways that there is an Amazon Cognito instance treatment users and auth, an AWS Appsync example handling the GraphQL API and an Amazon DynamoDB instance treatment data persistence.

Adding an S3 storage bucket.

First affair is to add the new Storage characteristic category to this existing backend. This is super piece of cake to exercise past running the dilate add together storage command in the terminal and selecting the post-obit options

Alt Text

Note - most of these are defaults apart from the 'Who should have admission' question where I have selected Auth users just and given them full CRUD privilege.

Adding an 'image' to our API definition

The adjacent step is to add together the concept of an image to our GraphQL schema definition. You can notice the schema definition under ./amplify/backend/api/myapi/schema.graphql

We simply add together a new String type called image - which will concur our image proper name when we persist an image and an image pre-signedURL when nosotros retrieve an prototype. The schema should now expect similar this

Alt Text

Note: if we desire to add FGAC to any of the fields in the schema we could apply the '@auth' transformer directive - for more detail on access control, transformer directives and @auth [read this article] https://aws.amazon.com/blogs/mobile/graphql-security-appsync-dilate/ - by Brice Pelle.

Once that has been updated, we become back to our terminal and run amplify update api control to regenerate the api definition. The output from this command should look similar to the below:

Alt Text

Once consummate we finally need to telephone call amplify push --y to push button all of our local changes into our cloud back end. This means that out dorsum-end services will now look like the following architectural diagram with the addition of the S3 bucket that the Amplify CLI Storage category has provisioned.

Alt Text

Updating the react native client awarding

So that is enough messing around in the last, now information technology'southward time to write some code. We volition be making all the changes in a single file App.js and the get-go thing we volition do is add in some additional state to store the image name and the imageURI we want to add together to each todo. So, something similar

                          const              initialTodoState              =              {              name              :              ''              ,              description              :              ''              ,              epitome              :              ''              }              const              initialAppState              =              {              showForm              :              faux              ,              imageURI              :              ''              }                      

Enter fullscreen mode Get out fullscreen way

Notation - All of the code for the finished app tin can be plant here

Selecting Images

Once we accept that we need to write a function that locates images on the device and displays them for the user to select. Luckily there is a tertiary-political party library chosen React Native Image Picker that will do most of this for us. And so, let's create a part to call this library, it should expect something like this.

                          handleChoosePhoto              =              async              ()              =>              {              endeavor              {              launchImageLibrary              ({              mediaType              :              '              photo              '              ,              includeBase64              :              false              ,              maxHeight              :              200              ,              maxWidth              :              200              ,              },              (              response              )              =>              {              if              (              response              .              uri              )              {              updateAppState              (              '              imageURI              '              ,              response              .              uri              )              const              filename              =              uuid              .              v4              ()              +              '              _todoPhoto.jpg              '              updateTodoState              (              '              prototype              '              ,              filename              )              }              })              }              grab              (              mistake              )              {              console              .              log              (              error              )              }              }                      

Enter fullscreen way Exit fullscreen mode

The handleChoosePhoto office is calling the launchImageLibrary function, that is office of react-native-image-picker's api. We are simply passing in some options like, image type , image height and image width and from the response we become the imageURI ( the location on the image on the device ) and nosotros relieve this and a unique image name in the state fields we created before.

Annotation: Nosotros a using the react-native-uuid library to make sure all images have unique names - this makes it easier when nosotros shop these names in DynamoDB.

When implemented the 'handleChoosePhoto' UI looks like this:
Alt Text

Uploading Images

Once we select the epitome, we can at present create a Todo in the 'create view' that contains the image we have selected by only adding the following tag in the App.js 'render' function

                          <              Image              source              =              {{              uri              :              todo              .              prototype              }}              manner              =              {              styles              .              image              }              /              >                                    

Enter fullscreen style Leave fullscreen fashion

which should look something similar this after adding in the appropriate tag.

Alt Text

Nosotros adjacent need to implement the office that is called past the 'Create Todo' button. This addTodo() part is where we add together the image upload code to the existing GraphQL api phone call as shown beneath

                          async              role              addTodo              ()              {              try              {              // new code for images              const              photo              =              await              fetch              (              appstate              .              imageURI              )              const              photoBlob              =              wait              photo              .              blob              ();              await              Storage              .              put              (              todoState              .              image              ,              photoBlob              ,              {              level              :              '              private              '              ,              contentType              :              '              image/jpg              '              })              //existing api lawmaking              const              todo              =              {              ...              todoState              }              setTodos              ([...              todos              ,              todo              ])              wait              API              .              graphql              (              graphqlOperation              (              createTodo              ,              {              input              :              todo              }))              setTodoState              (              initialTodoState              )              setAppState              (              initialAppState              )              }              grab              (              err              )              {              console              .              log              (              '              error creating todo:              '              ,              err              )              }              }                      

Enter fullscreen style Go out fullscreen mode

Here we are fetching the blob of the photo we have selected using the stored imageURI and so passing the result along with the unique image proper name to the Dilate Storage.put() call. Not forgetting as we are using a new Amplify category of 'Storage' we need to import the relevant libraries at the top of App.js in the imports department

                          import              {              API              ,              graphqlOperation              ,              Storage              }              from              '              aws-amplify              '                      

Enter fullscreen fashion Go out fullscreen mode

Once we have stored the blob in S3 using Storage.put() the last part of the function persists the image name along with all the other todo information in DynamoDB via the AppSync GraphQL api call, before finally re-setting whatever state.

Downloading Images

So now we have our image uploaded as part of the 'create view', the terminal step is to view the images when our initial 'list view' displays. It is currently looking very empty
Alt Text

To implement this, we first of all add together in an prototype tag to the UI that renders the list.

                          <              Image              source              =              {{              uri              :              todo              .              epitome              }}              fashion              =              {              styles              .              image              }              />                                                                

Enter fullscreen mode Exit fullscreen mode

And then nosotros update the fetchTodos function to retrieve the relevant image for every Todo we accept in our list.

                          async              function              fetchTodos              ()              {              try              {              //fetch the recipes from the server              const              todoData              =              expect              API              .              graphql              (              graphqlOperation              (              listTodos              ));              let              todos              =              todoData              .              data              .              listTodos              .              items              // for all todos get the pre-signURL and store in images field              todos              =              await              Promise              .              all              (              todos              .              map              (              async              (              todo              )              =>              {              const              imageKey              =              expect              Storage              .              get              (              todo              .              image              ,              {              level              :              '              individual              '              })              console              .              log              (              imageKey              )              todo              .              image              =              imageKey              ;              return              todo              ;              }));              setTodos              (              todos              )              setTodoState              (              initialTodoState              )              setAppState              (              initialAppState              )              }              take hold of              (              err              )              {              console              .              log              (              '              error fetching todos                            '              )              +              err              }              }                      

Enter fullscreen style Go out fullscreen style

And that is it!! your app should at present await like this, where the prototype is downloaded into the app from the S3 bucket using the pre-signed URL that Storage.get() so conveniently generates.

Alt Text

Conclusion

And then that is it, in a few minutes nosotros have added an image upload and download feature into our existing react native application.

All nosotros needed to exercise is update our backend using the Amplify CLI to provision our S3 bucket and change the schemas of our DynamoDB table and Appsync API. Then using the Dilate client libraries write a Storage.put() function and a Storage.get() function to add together and retrieve the images. The effect was not only fast to achieve, only also came with security built in.

Thanks for reading, hopefully this makes calculation this kind of feature to your react native application a breeze - if y'all would similar me to go into more than detail on any of the features of AWS Amplify or indeed annihilation AWS related in a future post - but post in the comments beneath.

Besides, whatever feedback is ever welcome either hither or catch me on the socials.

klassenthades.blogspot.com

Source: https://dev.to/aws/adding-image-upload-to-a-react-native-app-with-aws-amplify-4j7m

0 Response to "How to Upload Images in S3 Bucket Using React"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel