🤳

FlutterからS3を操作する① -設定編-

2022/06/26に公開

前置き

Firebase Storageへ画像をアップする方法はよく見ますが、PJによっては画像をS3へアップしたいこともあると思います。意外とサクッとできるので、備忘録、これから実装したい人への手助けになれば良いなあと思います。

こちらの記事とMinioの公式説明を参考に実装しました🙏
https://qiita.com/hmatsu47/items/86a9c028bb5b3beeebdd

前提条件

  1. AWSのIAMの設定、S3のバケット作成諸々が済んでいる。
  2. iOS、カメラとライブラリアクセスの設定が済んでいる。

S3って何?

Firebase Storage(Google)のAWS版です。(雑)

【よく出てきそうなワード】

  • IAM
    →AWSにアクセスするためのアカウント情報みたいなもの。個人的にはS3を使う場合、S3のフルアクセス権限を付けてもらってアカウント作成を依頼することが多いです。

  • シークレットキーとアクセスキー
    →IAMを作成した時に、発行されるもの。取扱注意なやつ。これを使ってAWSの各種あれこれをいじる。今回だとS3へアクセスする時に使用します。
    ※IAMのアクセス権限にないものは操作できないので注意です。

  • バケット
    →保存する入れ物みたいなもの。Gitでいうリポジトリです。知らんけど。

  • 署名付きURL
    →URLに文字くっつけて、アクセス有効期限を付けたやつ。ごめん、詳しくはこちらの記事を見てね。

https://qiita.com/tmiki/items/87697d3d3d5330c6fc08

モバイルアプリエンジニアは正直そこまでAWSをガッツリやることはないと信じているので、最低限この辺りがなんとなく頭に入っていれば良いかなと思います。

使用ライブラリ

pubspec.yaml
name: demo_profile_page
description: A new Flutter project.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1

environment:
  sdk: ">=2.17.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^1.0.2
  provider: ^6.0.1
  state_notifier: ^0.7.2+1
  flutter_state_notifier: ^0.7.1
  freezed_annotation: ^1.1.0
  image_picker: ^0.8.5
  flutter_dotenv: ^5.0.2
  minio: ^3.5.0
  uuid: ^3.0.6
dev_dependencies:
  flutter_test:
    sdk: flutter
  flutter_lints: ^2.0.1
  build_runner: ^2.1.7
  freezed: ^1.1.1
  json_serializable: ^6.1.5
flutter:
  uses-material-design: true

  assets:
    - .env.dev // 使用する.envをここで読み込む
    - assets/
    - assets/images/

S3のアップロードに今回使用するライブラリは↓これです。

  • image_picker
    →アプリから端末内のカメラ起動、ライブラリ画像選択するのに使用します。

https://pub.dev/packages/image_picker

  • flutter_dotenv
    →S3アクセスに必要な情報をenvで管理します。

https://pub.dev/packages/flutter_dotenv

envはgit管理から外しておきます。

.gitignore
.env.dev
.env
  • minio
    →S3を操作する時に使用します。

https://pub.dev/packages/minio

※状態管理はstate_notifierを今回使用しますが、この辺りはPJに合わせてくださいまし。

内部フロー

アップロード(削除)↓

画像閲覧(署名付きURL取得)↓

Minioの設定

pubspec.yamlに書いた.envファイルをloadします。

main.dart
import 'package:demo_profile_page/app.dart';
import 'package:demo_profile_page/router.dart';
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';

import 'build_config.dart';
import 'di/product_component.dart';

Future<void> main() async {
  
  ーー割愛ーー

  await dotenv.load(fileName: ".env.dev");

    ーー割愛ーー
  
}

envの中身はこんな感じ↓(ここは適宜書き換えてください。)

.env.dev
END_POINT=s3-ap-northeast-1.amazonaws.com
REGION=ap-northeast-1
ACCESS_KEY=アクセスキー
SECRET_KEY=シークレットキー
BUCKET=バケット名

Minioを共通で使用したいのでインスタンスを作成して、DIしてます。
(アプリ起動時にProviderで流す感じ)

import 'package:demo_profile_page/build_config.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:minio/minio.dart';
import 'package:provider/provider.dart';
import 'package:provider/single_child_widget.dart';

import 'component.dart';

class DependencyInjectionComponent implements Component {
  final BuildConfig config;

  const DependencyInjectionComponent(this.config);

  
  List<SingleChildWidget> provides() {
    final s3 = Minio(
      endPoint: dotenv.env['END_POINT']!,
      region: dotenv.env['REGION']!,
      accessKey: dotenv.env['ACCESS_KEY']!,
      secretKey: dotenv.env['SECRET_KEY']!,
      useSSL: true,
    );

    return [
      Provider<Minio>.value(value: s3),
      ...];
  }
}

設定編終わり

②の画像アップロード/削除編へ続きます!

https://zenn.dev/ohtsuki/articles/605975d1a0880b

Discussion

ログインするとコメントできます