Skip to main content

Dart and Flutter

There is no official AWS SDK for Dart, but the minio Dart package is a mature S3 client that works against any S3-compatible service.

Install

pubspec.yaml
dependencies:
minio: ^3.5.0

Initialize the client

lib/filebase.dart
import 'package:minio/minio.dart';

final filebase = Minio(
endPoint: 's3.filebase.io',
accessKey: const String.fromEnvironment('FILEBASE_KEY'),
secretKey: const String.fromEnvironment('FILEBASE_SECRET'),
region: 'auto',
useSSL: true,
);

List buckets

final buckets = await filebase.listBuckets();
for (final b in buckets) {
print(b.name);
}

Create a bucket

await filebase.makeBucket('my-bucket');

Upload an object

import 'dart:io';

final file = File('photo.jpg');
final stream = file.openRead().cast<List<int>>();
final length = await file.length();

await filebase.putObject(
'my-bucket',
'photo.jpg',
stream,
size: length,
metadata: {'Content-Type': 'image/jpeg'},
);

For Flutter mobile uploads, the image_picker plugin gives you an XFile:

import 'package:image_picker/image_picker.dart';

final picker = ImagePicker();
final XFile? image = await picker.pickImage(source: ImageSource.gallery);

if (image != null) {
final bytes = await image.readAsBytes();
await filebase.putObject(
'uploads',
'user-${userId}/${image.name}',
Stream.value(bytes),
size: bytes.length,
);
}

List objects

final stream = filebase.listObjects('my-bucket', prefix: 'photos/');
await for (final result in stream) {
for (final obj in result.objects) {
print('${obj.key} ${obj.size}');
}
}

Download an object

import 'dart:io';

final stream = await filebase.getObject('my-bucket', 'photo.jpg');
final file = File('./downloaded.jpg');
final sink = file.openWrite();
await stream.pipe(sink);

Delete an object

await filebase.removeObject('my-bucket', 'photo.jpg');

Pre-signed URLs

final url = await filebase.presignedGetObject(
'my-bucket',
'private.pdf',
expires: 3600,
);

print(url);

Error handling

try {
await filebase.statObject('my-bucket', 'maybe.jpg');
} on MinioError catch (e) {
if (e.code == 'NoSuchKey') {
// handle missing
} else {
rethrow;
}
}

What's next