26
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Flutterアプリのアーキテクチャについて2

Last updated at Posted at 2019-12-09

はじめに

前回のアーキテクチャ1に続く2になります。今回はDBから値を取得して一覧表示するユースケースをまとめます。

DBに何を使うのか?

サーバサイドを開発するのであればHerokuを使う、AwsのLambdaでサーバレスで構築など色々選択肢がありますが、ライトにアプリを作るのであれば、FirebaseのFirestoreを使うと便利です。Firestoreを使うとFlutterのコードだけでデータの永続化、永続化したデータの画面へのリアルタイムな反映が行なえます。また料金も無料から始めることができます。

Stream vs Future

Firestoreから値を取得するには、Firestore上のCollectionの変更を監視しリアルタイムに画面に値を反映できる、 StreamとFutureがありますが、Streamを使うことで、Firestoreの強みであるリアルタイム反映を実現できるので、Streamを使っていきます

全体アーキテクチャ

登場するクラスが複数あるので最初に、全体の構成図をまとめておきます。
スクリーンショット 2019-12-09 8.57.46.png

FirestoreからDataSourceクラスで値を取得し、StreamProviderを使ってBuildContextに値を注入し、Widgetでその値を使います。またFIrebaseのDocumentを表現するEntityクラスを作成します。

Firestoreのコレクション構成

Firestoreのコレクション構成は下記のとおりです
スクリーンショット 2019-12-09 9.02.50.png

Entity

FirestoreのDocumentを表すモデルクラスです。コンストラクタfromDocumentSnapshotを用意し、DocumentSnapshotからインスタンスを生成できるようにしておきます。

entity.dart
class Entity {
  final String name;
  
  Entity({@required this.name});

  factory Entity.fromDocumentSnapshot(DocumentSnapshot doc) => Entity(name: doc['name']);
}

DataSource

FirestoreからStrem形式でデータを取得します。Collectionのsnapshotに対して、asyncMapすることで、Firestoreで変更があった内容をリアルタイムに反映できるようになります。snapshotはQuerySnapshotクラスのためdocumentsで実際のコレクションの内容であるドキュメントの配列を取得し、mapでEntityに変換します。

data_source.dart
class DataSource {

  final db = Firestore.instance;

  Stream<List<Entity>> streamList() =>
      db.collection('hoge').snapshots().asyncMap((snapshot) =>
          snapshot.documents.map((doc) => Entity.fromDocumentSnapshot(doc)).toList());
}

Widget

実際に値を使用するWidgetクラスです。アーキテクチャ1と同様に、Staticメソッドでデータ注入部を作成します。
StreamProviderクラスを使用すると、StreamをBuildContextに埋め込むことができます。initialDataでからの配列をしておくと、データ取得前にProviderからnullが渡り後続の処理がnullになることを防ぐことができます。

実際使用する部分では Provider.of<List<Entity>>(context)List<Entuty>>を簡単に取り出すことができます。

hoge_screen.dart
class HogeScreen extends StatelessWidget {
  static Widget withDependencies() => StreamProvider<List<Entity>>(
        create: (_) => DataSource().streamList(),
        initialData: [],
        child: HogeScreen(),
      );

  @override
  Widget build(BuildContext context) => ListView(
        children: _buildList(context),
      );

  List<Widget> _buildList(BuildContext context) =>
      Provider.of<List<Entity>>(context)
          .map((entity) => Text(entity.name))
          .toList();
}

まとめ

FirestoreとFlutterを使うと簡単にリアルタイムに反映される一覧を作ることができます。アーキテクチャ迷ってる人は是非試してみてください

26
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?