Uploading images to AWS S3 with Flutter — Part 1
Welcome to this tutorial for uploading images to AWS S3 — part 1
You can connect with me on Instagram
Make sure you also checkout the new updated article for uploading single photo-
Let’s start by seeing our end goal
Disclaimer: This might be more than what you were looking for.
If you just want to know how to upload files to AWS S3, check the Problem 3 solution.
Breaking down
- Handle photos permission
- Open image picker, select and load image
- Upload image to AWS S3 bucket
- Show loading and error uploading image
- Open image
- Save images
- Delete image
Let’s solve problem 1 first
First we need a starter code for layout-
Lets check the output-
What did we do?
- Add flutter_icons: ^1.0.0+1 to pubspec.yaml
- We created a list view with at least 1 item
- The first item is used to add photos
- More images will be added to the end of the list
- We also added a PhotoSource list which will keep the source of each image
Now let's handle permissions-
Let's check the output-
For Android-
For IOS-
What did we do?
- Added library permission_handler: ^5.0.0+hotfix.3 to pubspec.yaml.
- Created a common class to display dialogs based on platform.
- As you can see from the above two videos, different dialog is shown based on platform.
Lets see the program flow
NOTE: In the above videos, the app is installed with no existing version.
NOTE 2: We need storage permission from Android and photos permission for IOS.
For Android-
When clicking on add photo button
- For the first time- Permission status is undetermined and we can ask the user for permission. What we do- We deny the permission.
- For the second time- Permission status is denied, but we can still ask the user for permission. What we do- We deny the permission with the option to Don’t ask again.
- For the third time- Permission status is permanentlyDenied because we selected the Don’t ask again option. So if we request permission again, we won’t see that dialog. But to still allow the user to change permission, we show user a dialog which lets the user go to the app settings and change permission. What we do- Change the storage permission from Off to On.
- For the fourth time- Permission status is granted because we changed and allowed the permissions from app settings.
For IOS-
When clicking on the add photo button
- For the first time- Permission status is undetermined and we can ask the user for permission. What we do- We deny the permission.
- For the second time- Permission status is denied. So if we request permission again we won’t see that dialog, but to still allow the user to change permission, we show the user a dialog which lets the user go to the app settings and change permission. What we do- Change the permission from Never to Read and Write.
- For the third time- Permission status is granted because we changed and allowed the permissions from app settings.
As we can see, in case of permission status is denied, we can request permission in Android but not in IOS.
Problem 1 solved.
Let’s solve problem 2 now
Problem 2: Open image picker, select and load image
NOTE: We also added a GalleryItem list to _ImagePickerWidgetState class
Let's check the output-
For Android-
For IOS-
What did we do?
- Added library image_picker: ^0.6.4, uuid: ^2.0.4 and path: ^1.6.4 to pubspec.yaml.
- If the permission is granted, we will use the image_picker to open gallery.
- If an image was selected, we will add that photo to our lists and use setState() to refresh
Problem 2 is solved.
Lets solve problem 3 now
Problem 3: Upload image to AWS S3 bucket
Prerequisite:
- A public bucket in AWS S3
- Access token and secret token with access to AWS S3 bucket
To create a public bucket:
Step 1: Login or Create an account on AWS
Step 2: Go to AWS S3 Service
Step 3: Create a bucket with public access and region based on your users' geolocation
To Create/Get access token and secret token:
Step 1: Go to Amazon Web Services console and click on the name of your account (it is located in the top right corner of the console). Then, in the expanded drop-down list, select Security Credentials.
Step 2: Expand the Access Keys (Access Key ID and Secret Access Key) option. You will see the list of your active and deleted access keys.
Step 3: To generate new access keys, click the Create New Access Key button.
Step 4: Click Show Access Key to have it displayed on the screen. Note, that you can download it to your machine as a file and open it whenever needed. To download it, just click the Download Key File button.
IMPORTANT: If you do not download the key file to your computer before you press “Close” or “Cancel” you will not be able to retrieve the secret key in future.
Now that we have all the prerequisites, lets start uploading.
What will be use?
NodeJs server with express framework.
How will we upload images?
- Request our NodeJs server to give us a download and upload Url.
- Then upload the image to the upload Url.
- Save the download url and use it to show images.
Lets get the server ready first
It's already ready for you :)
What do you need to do?
- Download the repository
- Update config-aws.js.
- Open repository in terminal
- Install node packages using npm install
- Run server using npm start
Now the server is ready and running.
Now lets upload images from app
IMPORTANT: Remember to use url in GenerateFileUrl based on your emulator.
What did we do?
- Added library http: ^0.12.0+4 to pubspec.yaml.
- Called our NodeJs function from GenerateImageUrl to return an upload and download url as the response.
- Then stored the upload and download url in our generateImageUrl object instance.
- Then use the UploadFile object instance in uploadFile function to upload image to upload url.
- If the upload is successful, we add the download url to photoUrls list.
Let's check the output-
For Android-
For IOS-
Let's check our AWS S3 bucket-
Now we have both the files we uploaded in our AWS S3 bucket.
Problem 3 is solved.
Part 2 is available here.
Check the full project here.
Thank you for staying
More flutter spinner blogs
I will be posting more about flutter, so stay tuned :)