[Flutter] Upload image via AWS S3

Jason Choi
3 min readMar 22, 2021

From Cloudinary To AWS S3

There was a problem with image uploading in my Flutter project.

I initially used Cloudinary, because it was easy to apply to Flutter.

The code for Cloudinary was like the following:

Future<String> uploadFile(String filePath) async {try {final bytes = File(filePath).readAsBytesSync();String base64Encode(List<int> bytes) => base64.encode(bytes);String JPEGPrefix = ‘data:image/jpeg;base64,’;// print(base64Encode(bytes).substring(0, 100));const URL = ‘https://api.cloudinary.com/v1_1/account_name/image/upload/';Response response = await Dio().post(URL, data: {‘file’: JPEGPrefix + base64Encode(bytes),‘upload_preset’: ‘preset_name',‘folder’: ‘folder1/userProfileImages’,});print(response.data[“url”]);return response.data[“url”];} catch (e) {print(e);return e;}}

It worked well, with one problem. — It was too late to upload the image.

It took 10 seconds to upload one image; If user chose 5 images, then it took almost one minutes — infinity for an app user.

So, I tried these:

https://support.cloudinary.com/hc/en-us/community/posts/201449521-Can-Cloudinary-resize-an-image-server-side-upon-upload-to-save-storage-space-

But even after I applied these, the speed didn’t descrease.

That made me try another alternative: firebase storage.

Unfortunately, it didn’t work, too. There was a problem installing packages to my Flutter project. It conflicted with other packages.

That’s why I chose to use AWS S3 as image uploading cloud.

There’s a Flutter package named aws_s3, but it conflicted with my packages.

I mostly referenced this article by AWS officially:

And this helps too.

https://docs.amplify.aws/lib/storage/getting-started/q/platform/flutter

It shows step-by-step approach to AWS Amplify, so there’s not so much need for explanation.

Sample code

main.dart

void _configureAmplify() async {// Add Pinpoint and Cognito Plugins, or any other plugins you want to use// run amplify add analytics to use analyticsAmplifyAnalyticsPinpoint analyticsPlugin = AmplifyAnalyticsPinpoint();AmplifyAuthCognito authPlugin = AmplifyAuthCognito();Amplify.addPlugins([authPlugin, analyticsPlugin, AmplifyStorageS3()]);// Once Plugins are added, configure Amplify// Note: Amplify can only be configured once.try {await Amplify.configure(amplifyconfig);} on AmplifyAlreadyConfiguredException {print(“Tried to reconfigure Amplify; this can occur when your app restarts on Android.”);}}

upload_file.dart

Future<String> uploadToS3(String filePath) async {// final key = new DateTime.now().toString();
// I changed key to avoid URI encoding problem, and added one random string to enable simultaneous upload
final key = DateTime.now().microsecondsSinceEpoch.toString() + randomAlpha(1);Map<String, String> metadata = <String, String>{};metadata[‘name’] = ‘filename’;metadata[‘desc’] = ‘A test file’;S3UploadFileOptions options = S3UploadFileOptions(accessLevel: StorageAccessLevel.guest, metadata: metadata);try {UploadFileResult result = await Amplify.Storage.uploadFile(key: key, local: File(filePath), options: options);print(result.key);String resultURL =“https://cloudfront_id.cloudfront.net/public/" + result.key;return resultURL;} on StorageException catch (e) {print(e.message);}}

I used AWS Cloudfront to make image load faster.

You can refer here:

Ta-da! The time taken to upload image is decreased about 5x times.

--

--