## Upload File To upload to S3 from a file, specify the `key` and the `localFile` to be uploaded, where the `localFile` can be an instance of `AWSFile` created from either an OS platform `File` instance or the result of Flutter file picker plugins such as [file_picker](https://pub.dev/packages/file_picker). ### Upload platform `File` **Note**: To use `AWSFilePlatform`, add [aws_common](https://pub.dev/packages/aws_common) package to your Flutter project by running: `flutter pub add aws_common` ```dart import 'dart:io' as io; import 'package:amplify_storage_s3/amplify_storage_s3.dart'; import 'package:aws_common/vm.dart'; Future uploadIOFile(io.File file) async { final awsFile = AWSFilePlatform.fromFile(file); try { final uploadResult = await Amplify.Storage.uploadFile( localFile: awsFile, key: 'upload/file.png', ).result; safePrint('Uploaded file: ${uploadResult.uploadedItem.key}'); } on StorageException catch (e) { safePrint('Error uploading file: ${e.message}'); rethrow; } } ``` ```dart import 'dart:html' as html; import 'package:amplify_storage_s3/amplify_storage_s3.dart'; import 'package:aws_common/web.dart'; Future uploadHtmlFile(html.File file) async { final awsFile = AWSFilePlatform.fromFile(file); try { final uploadResult = await Amplify.Storage.uploadFile( localFile: awsFile, key: 'upload/file.png', ).result; safePrint('Uploaded file: ${uploadResult.uploadedItem.key}'); } on StorageException catch (e) { safePrint('Error uploading file: ${e.message}'); rethrow; } } ``` ### Upload with Flutter file_picker plugin The [file_picker](https://pub.dev/packages/file_picker) plugin can be used to retrieve arbitrary file types from the user's device. ```dart import 'package:amplify_flutter/amplify_flutter.dart'; import 'package:file_picker/file_picker.dart'; Future uploadImage() async { // Select a file from the device final result = await FilePicker.platform.pickFiles( type: FileType.custom, withData: false, // Ensure to get file stream for better performance withReadStream: true, allowedExtensions: ['jpg', 'png', 'gif'], ); if (result == null) { safePrint('No file selected'); return; } // Upload file with its filename as the key final platformFile = result.files.single; try { final result = await Amplify.Storage.uploadFile( localFile: AWSFile.fromStream( platformFile.readStream!, size: platformFile.size, ), key: platformFile.name, onProgress: (progress) { safePrint('Fraction completed: ${progress.fractionCompleted}'); }, ).result; safePrint('Successfully uploaded file: ${result.uploadedItem.key}'); } on StorageException catch (e) { safePrint('Error uploading file: $e'); rethrow; } } ``` ## Upload Data To upload to S3 from a data object, specify the `key` and `data`, where `data` is an instance of `S3DataPayload` created from various data formats. ```dart import 'package:amplify_flutter/amplify_flutter.dart'; import 'package:amplify_storage_s3/amplify_storage_s3.dart'; Future uploadStringData({ required String dataString, required String key, }) async { try { final result = await Amplify.Storage.uploadData( data: S3DataPayload.string( dataString, contentType: 'text/plain', ), key: key, ).result; safePrint('Uploaded data: ${result.uploadedItem.key}'); } on StorageException catch (e) { safePrint('Error uploading data: ${e.message}'); rethrow; } } ``` ```dart import 'package:amplify_flutter/amplify_flutter.dart'; import 'package:amplify_storage_s3/amplify_storage_s3.dart'; Future uploadJsonObject({ required Map json, required String key, }) async { try { final result = await Amplify.Storage.uploadData( data: S3DataPayload.json(json), key: key, ).result; safePrint('Uploaded data: ${result.uploadedItem.key}'); } on StorageException catch (e) { safePrint('Error uploading data: ${e.message}'); rethrow; } } ``` `S3DataPayload.dataUrl()` parses the provided data URL string, and throws exception if the data URL is invalid. See more info about [data URL](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs). ```dart import 'package:amplify_flutter/amplify_flutter.dart'; import 'package:amplify_storage_s3/amplify_storage_s3.dart'; Future uploadDataUrl({ required String dataUrl, required String key, }) async { try { final result = await Amplify.Storage.uploadData( data: S3DataPayload.dataUrl(dataUrl), key: key, ).result; safePrint('Uploaded data: ${result.uploadedItem.key}'); } on StorageException catch (e) { safePrint('Error uploading data: ${e.message}'); rethrow; } } ``` ```dart import 'package:amplify_flutter/amplify_flutter.dart'; import 'package:amplify_storage_s3/amplify_storage_s3.dart'; Future uploadBytes({ required List bytes, required String key, required String contentType, }) async { try { final result = await Amplify.Storage.uploadData( data: S3DataPayload.bytes( bytes, contentType: contentType, ), key: key, ).result; safePrint('Uploaded data: ${result.uploadedItem.key}'); } on StorageException catch (e) { safePrint('Error uploading data: ${e.message}'); rethrow; } } ``` ## Upload Options You can attach metadata while uploading data or a file by specifying the `metadata` property in options. If you want the `metadata` to be included in the upload result, you can set the `getProperties` flag to `true` in options. ```dart Future uploadWithOptions() async { // When uploading data, use `StorageUploadDataOptions` final uploadDataOperation = Amplify.Storage.uploadData( data: S3DataPayload.string( 'example', contentType: 'text/plain', ), key: 'example.txt', options: const StorageUploadDataOptions( metadata: { 'project': 'ExampleProject', }, pluginOptions: S3UploadDataPluginOptions( getProperties: true, ), ), ); final uploadDataResult = await uploadDataOperation.result; safePrint( 'Uploaded data with metadata: ${uploadDataResult.uploadedItem.metadata}', ); // When uploading a file, use `StorageUploadFileOptions` final uploadFileOperation = Amplify.Storage.uploadFile( localFile: AWSFile.fromPath('path/to/example.txt'), key: 'example.txt', options: const StorageUploadFileOptions( metadata: { 'project': 'ExampleProject', }, pluginOptions: S3UploadFilePluginOptions( getProperties: true, ), ), ); final uploadFileResult = await uploadFileOperation.result; safePrint( 'Uploaded file with metadata: ${uploadFileResult.uploadedItem.metadata}', ); } ``` The [`Amplify.Storage.getProperties` API](/lib/storage/get-properties) allows you to retrieve metadata without downloading the file. In S3 console, you should see the metadata attached to your file as the following. ![S3 Metadata](/images/s3_metadata.png) ## Control of Upload Operations A call to `Amplify.Storage.uploadFile` or `Amplify.Storage.uploadData` returns a reference to the operation that is performing the upload. To cancel the upload (for example, in response to the user pressing a Cancel button), simply call `.cancel()` on the returned upload operation. ```dart import 'package:amplify_flutter/amplify_flutter.dart'; import 'package:amplify_storage_s3/amplify_storage_s3.dart'; S3UploadFileOperation? uploadOperation; Future uploadFile(String path) async { try { final storagePlugin = Amplify.Storage.getPlugin(AmplifyStorageS3.pluginKey); uploadOperation = storagePlugin.uploadFile( localFile: AWSFile.fromPath(path), key: 'example_file.txt', ); final result = await uploadOperation!.result; safePrint('Uploaded ${result.uploadedItem.key}'); } on StorageException catch (e) { safePrint('Error uploading file: ${e.message}'); } } void cancelUpload() { uploadOperation?.cancel(); uploadOperation = null; } ``` ## Multipart Upload Amplify will automatically perform a S3 multipart upload for files larger than 5MB. For more information about S3's multipart upload support, see [Uploading and copying objects using multipart upload](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html).