この記事は、株式会社ゆめみの23卒 Advent Calendar 2023のアドベントカレンダーになります!!
色々な種類の記事が投稿されるので、お楽しみに🤗
こんにちは。いせりゅーです。今回は、Flutter x Supabaseで画像のアップロードする方法に加えて、必要そうな記載を書いてみました。(あくまでも一例です)
Supabaseを学習し始めてからまもないため、間違えた実装を記載するかも知れません。その場合はコメントなどで教えていただけると幸いです🙇
1、カメラかカメラロールか選択するSheetを出す。
2、ImagePickerで写真を取得する
3、画像をアップロードする。
こんな感じで進めていきます〜〜!!
カメラorカメラロールか選択するSheetを出す。
写真をアップロードする場合において、「カメラ」か「カメラロール」の2種類で画像をアップロードすることが多いと思います。
これの表現方法はいくらでもありますが、今回は、Sheetを出す形にしてみました。iOS風にしたかったためshowCupertinoModalPopup
を使用してみました。
void onTapImage() {
showCupertinoModalPopup(
context: context,
builder: (context) => CupertinoActionSheet(
actions: [
CupertinoActionSheetAction(
isDefaultAction: true,
onPressed: () {
Navigator.pop(context);
camera();
},
child: const Text(
'カメラ',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
),
CupertinoActionSheetAction(
onPressed: () {
Navigator.pop(context);
album();
},
child: const Text(
'アルバム',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
),
CupertinoActionSheetAction(
isDestructiveAction: true,
onPressed: () => Navigator.pop(context),
child: const Text('閉じる'),
),
],
),
);
}
void camera() {
}
void album() {
}
ImagePickerで写真を取得する
次に画像を取得する処理を記載します。今回は、image_pickerを導入しました。
Androidのセットアップ
<uses-permission android:name="android.permission.CAMERA" />
defaultConfig {
applicationIdSuffix appIdSuffix
// minSdkVersion 19
minSdkVersion 21
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
resValue "string", "app_name", appName
}
iOSのセットアップ
<key>NSPhotoLibraryUsageDescription</key>
<string>写真の投稿のために許可が必要になります</string>
<key>NSCameraUsageDescription</key>
<string>写真の投稿のために許可が必要になります</string>
画像を取得する
final picker = ImagePicker();
String uploadImage = '';
// カメラからの画像を取得する
Future<void> camera() async {
try {
final image = await ImagePicker().pickImage(source: ImageSource.camera);
if (image == null) {
return;
}
imageBytes = await image.readAsBytes();
uploadImage = image.name;
print('画像の添付が成功しました');
} on PlatformException catch (error) {
print(error);
}
}
Future<void> album() async {
try {
final image = await ImagePicker().pickImage(source: ImageSource.gallery);
if (image == null) {
return;
}
imageBytes = await image.readAsBytes();
uploadImage = image.name;
print('画像の添付が成功しました');
} on PlatformException catch (e) {
state = state.copyWith(status: e.message!);
}
}
画像をアップロードする。
では、Supabaseに画像をアップロードしていこうと思います。
その前にSupabase側で設定が必要そうですね。こちらを参考にしてみてください(今回は割愛させていただきます)
今回は、画像のPathをid/画像のパス
にしてみました。理由としては、どのユーザーが投稿したかをわかりやすくするためでした。(もっといい方法があれば知りたい😇)
final supabase = Supabase.instance.client;![スクリーンショット 2023-12-01 12.12.50(2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/672609/4d213fd7-f6ff-a7c5-444c-7bf7eb0f5bfa.png)
Future<void> upload() async {
loading.state = true;
final user = supabase.auth.currentUser?.id;
try {
await supabase.storage.from('food').uploadBinary('/$user/$uploadImage', imageBytes);
} on PostgrestException catch (error) {
print(error);
}
}
ソースコード
final picker = ImagePicker();
String uploadImage = '';
final supabase = Supabase.instance.client;
void onTapImage() {
showCupertinoModalPopup(
context: context,
builder: (context) => CupertinoActionSheet(
actions: [
CupertinoActionSheetAction(
isDefaultAction: true,
onPressed: () {
Navigator.pop(context);
camera();
},
child: const Text(
'カメラ',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
),
CupertinoActionSheetAction(
onPressed: () {
Navigator.pop(context);
album();
},
child: const Text(
'アルバム',
style: TextStyle(
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
),
CupertinoActionSheetAction(
isDestructiveAction: true,
onPressed: () => Navigator.pop(context),
child: const Text('閉じる'),
),
],
),
);
}
Future<void> camera() async {
try {
final image = await ImagePicker().pickImage(source: ImageSource.camera);
if (image == null) {
return;
}
imageBytes = await image.readAsBytes();
uploadImage = image.name;
print('画像の添付が成功しました');
} on PlatformException catch (error) {
print(error);
}
}
Future<void> album() async {
try {
final image = await ImagePicker().pickImage(source: ImageSource.gallery);
if (image == null) {
return;
}
imageBytes = await image.readAsBytes();
uploadImage = image.name;
print('画像の添付が成功しました');
} on PlatformException catch (e) {
state = state.copyWith(status: e.message!);
}
}
Future<void> upload() async {
loading.state = true;
final user = supabase.auth.currentUser?.id;
try {
await supabase.storage.from('food').uploadBinary('/$user/$uploadImage', imageBytes);
} on PostgrestException catch (error) {
print(error);
}
}
最後に
自分もまだまだ学習中ですが、Supabaseのいいところが毎日見つかってきてとてもいいですね。個人的にはこれからの発展に期待したいですね😁
ちょっとした宣伝
株式会社ゆめみの23卒のメンバーでアドベントカレンダーを作成しています。
新卒のフレッシュな記事がたくさん投稿予定なので、少しでも興味があれば購読いただけると幸いです!!