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
- Open your project in Xcode
- Go to your info.plist
- 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)
- Go to your firebase console and open your project
- Go to the storage tab
- Click on "Get started"
- Click on "Next" and then "Done"
- Go to the "Rules" tab
- 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;
}
}
}
- 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.
-
- open the gallery
-
- transform the image to a reduced jpg in an isolate
-
- upload the image to the storage
-
- create a public URL to the image
-
- 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)