How to upload to DigitalOcean & Amazon S3 Spaces using Flutter?

For many of the app developers, you may not use your server for storage purposes where you make your API calls. It could be because the storage is expensive, the load on the server would be more when you would like to stream videos or you are using a server less (functions) technology. For such scenarios, you may consider using dedicated storage services, such as Amazon S3 or for this articles sake, DigitalOcean Spaces.

In this article, I would guide you how you can use DigitalOcean spaces from your Flutter application for uploading and downloading files. For starting, we would be using the following libraries (I have used these versions):

sigv4: ^4.1.1
dospace: ^0.12.14

You can create your DigitalOcean account by clicking here. If you already have one, then you can expand the manage on the left side menu and click on Spaces.

Then go ahead and click Create a Space and choose the Datacenter that is closest to your region. For example, Frankfurt is the closest to my region.

We can make the files private by selecting Restrict File Listing or make it public by click Enable File Listing.

Once the spaces have been created, click on Manage Keys for creating API keys for your spaces

And then on Spaces access keys, click Generate New Key. Note that you should copy the key somewhere safe because it would not display twice.

Well, that is all we have on DigitalOcean end. It is on the Flutter’s end for uploading and downloading the files.

Following is the code that creates an object of dospace and the path is set for DigitalOcean along with the function for uploading a local image to the spaces. The function will then return the path where it would be stored for saving it in the database.

dospace.Spaces spaces = new dospace.Spaces(
  region: 'YOUR-REGION',
  accessKey: 'YOUR-ACCESS-KEY',
  secretKey: 'YOUR-SECRET-KEY',
);
String basePathDigitalOcean = 'https://fra1.digitaloceanspaces.com/your-space/Videos';
Future<String> uploadMedia(File file) async {
var _fileName = Guid.newGuid.toString();
var _extension = p.extension(file.path);
var _contentType = 'image/' + _extension;
var _filePath = file.path;
var _filePathDigitalOcean = basePathDigitalOcean + '/' + _fileName + p.extension(file.path);
var bucket = spaces.bucket('your-space');
await bucket
.uploadFile(
'Files/' + (_fileName + p.extension(_filePath)),
file,
_contentType,
dospace.Permissions.private
);
return _filePathDigitalOcean;
}

After successfully saving the files, you can check in your spaces on DigitalOcean as the file have been uploaded.

It is time for downloading the file. For that, we need to have an object for Sigv4Client.

static final client = Sigv4Client(
  keyId: 'YOUR-KEY-ID',
  accessKey: 'YOUR-ACCESS-KEY',
  region: 'YOUR-REGION',
  serviceName: 's3',
);

We used dio for downloading the content but Signv4Client is required for signing the headers.

static Future<String> downloadMedia(String mediaURL, String fileName) async {
  Dio dio = Dio();
  Options options = Options(headers: client.signedHeaders(mediaURL));
  File filePath;
  Directory _appDir = await getApplicationDocumentsDirectory();
  filePath = await File(_appDir.path + '/' + fileName).create(recursive: true);
  print(filePath.path);
  await dio.download(mediaURL, filePath.path, options: options);
  return filePath.path;
}

This function would download the file to the location specified and save it using the name fileName.

That’s it. If you have any confusions, feel free to write your comments below.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s