ApparenceKit Storage module

Install storage template

Run the following command:

dart pub global run apparence_cli storage --provider=generic

or if you want to use firebase storage:

dart pub global run apparence_cli storage --provider=firebase

this will install the following dependencies:

  • firebase_storage* (if you use firebase)
  • path_provider
  • image_picker
  • image

This will also add our storage module to your code. You will now find

  • a Storage api (lib/core/data/api/storage_api.dart)
  • an example of how to use the storage api (lib/modules/settings/ui/components/avatar_component.dart)
  • a template to edit the avatar of the user (lib/modules/settings/ui/components/edit_avatar_component.dart)

Android

Congratulations, there is nothing to do.

iOS

Setup your project

  1. Open your project in Xcode
  2. Go to your info.plist
  3. Add the NSPhotoLibraryUsageDescription key and a description of why you need to access the photo library

If you intend to get pictures from the camera: Add the NSCameraUsageDescription key and a description of why you need to access the camera

If you want to record videos: Add the NSMicrophoneUsageDescription key and a description of why you need to access the microphone

Setup external project

Using firebase storage you can directly upload files to firebase storage from your client and get the download url.

Setup Firebase Storage

(You need to have a firebase project and also use firebase_auth)

  1. Go to your firebase console and open your project
  2. Go to the storage tab
  3. Click on "Get started"
  4. Click on "Next" and then "Done"
  5. Go to the "Rules" tab
  6. Replace the content with the following:
rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if request.auth != null;
    }
  }
}
  1. Click on "Publish"

Note: these security rules are not secure, you should change them to fit your needs. This will allow anyone to upload files to your storage without any file limit.

Here is a more sofiticated example:

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
  	match /users/{id} {
      allow write, update: if request.auth != null && request.auth.uid == id && request.resource.size < 100 * 1024;
      allow read, delete: if request.auth != null && request.auth.uid == id;
    }
    match /{allPaths=**} {
      allow read, write, update, delete: if false;
    }
  }
}

This will allow users to upload files to their own folder and only if the file size is less than 100kb.

EditAvatar template

This template is used to edit the avatar of the user. You can use it once you have setup the storage module.

import 'package:apparence_kit/modules/settings/ui/components/avatar_component.dart'; 

...
EditableUserAvatar();

It will display the current avatar of the user and allow him to change it.

    1. open the gallery
    1. transform the image to a reduced jpg in an isolate
    1. upload the image to the storage
    1. create a public URL to the image
    1. update the user with the new avatar URL

You can also dig into the code to see how it works. You will learn how to upload files to storage and track the upload progress.

Uploading a file to storage

start by importing the storage api into a repository of your choice:

import 'package:apparence_kit/core/data/api/storage_api.dart';

then you can use the following method to upload a file to storage:

Stream<UploadResult> uploadData(
    Uint8List data,
    String folder,
    String filename, {
    String? mimeType, // ex 'image/jpg'
    bool isPublic = true,
  });
  • data: the data of the file you want to upload
  • folder: the folder in which you want to upload the file
  • filename: the name of the file you want to upload
  • mimeType: the mimeType of the file you want to upload
  • isPublic: if true, the file will be public and anyone will be able to access it

If you use your own backend the method is not implemented and you will have to implement it yourself.

Using Amazon S3 storage

I encourage you in this case to never upload files directly from the client to S3. You can ask your backend to create a presigned url for you and then upload the file to this url. As a result, you will not have to deal with the security of your S3 bucket on the client side. And your server won't have to upload the file to S3 for you.

You can also send the file to your backend and then upload it to S3 from your backend. (So you can remove the isPublic and folder parameters from the uploadData method)