🌟

【Flutter】個人開発でリリースした「フットサル分析アプリ」の技術的まとめ

2021/11/01に公開

はじめに

はじめまして,現在大学院に通いながらFlutterでアプリ開発をしているわかなおです!
Flutterの勉強はこちらのコミュニティに所属して行なっています!
https://kboyflutteruniv.com/
毎週勉強会があったり、優秀なFlutterエンジニアとも知り合えたり、初学者でも成長できる場があったりと非常に良質なコミュニティだと思います! Flutter大学なくして今のボクはないです!

今回はFlutterで「Futsal Analyse -フットサルの記録分析アプリ-」をリリースしたので,アプリ開発のために使用した技術についてまとめていきます。
アプリ概要

iOS
Android

開発の経緯

学部時代にフットサル部に所属していたのですが部活内の試合結果はすべて紙で記録されていました。せっかくのデータを有効に活用できないことがもったいないなと感じていて,データをアプリに落とし込み個人やチームの戦績を分析して「見える化」したら面白くなるぞと考えていました!
Flutter大学の共同開発にて筋肉日記を開発したり,アプリ開発のアルバイトをさせていただく中で,だんだんと力がついていき「これはもしかしたら形にできるかもしれないぞ。。。!」と思い,開発に着手しました。

概要

アプリの概要

「Futsal Analyse -フットサルの記録分析アプリ-」は主に以下の機能で構成されています。

  • 結果の記録
  • 結果の分析
  • 作戦ボード

試合結果を記録して,記録を元に決定率や得点ランキングなどの個人の戦績や,得失点や勝率などのチームの戦績を算出して表示させるシンプルなアプリです。

主な使用技術

  • Flutter
  • Firebase
    • Authentication
    • Cloud Firestore
    • Hosting
    • Cloud Functions

Flutter+Firebase

アーキテクチャ

providerを用いたMVVMで実装をしました。(次回はRiverpodを使いたい)

ChangeNotifierを使ってWidgetに変更を通知させてStatelessWidgetの画面を更新させています。これにより状態とロジックをWidget(View)から分離させています。

MVVMについての詳しい情報については以下の記事がとても参考になりました
https://note.com/yasukotelin/n/n3cdd311fb336
https://wasabeef.medium.com/flutter-を-mvvm-で実装する-861c5dbcc565

使用した主なライブラリ

provider
Flutterの状態管理に使用。
firebase_core
FirebaseCoreAPIを使用するFlutterプラグイン。複数のFirebaseアプリへの接続を可能にする
cloud_firestore
Cloud FirestoreAPIを使用するためのプラグイン。
firebase_auth
FirebaseAuthenticationAPIを使用するためのプラグイン。認証周りを簡単に実装できます。
email_validator
メールアドレスのバリデーションのために使用。
charts_flutter
グラフ描画のために使用。
flutter_slidable
"LINEの友だちブロックのスライド"のような動きを実装するために使用。
flutter_launcher_icons
iOSとAndroidのアプリアイコンを生成するために使用。
flutter_native_splash
スプラッシュ画面の実装に使用。
introduction_screen
初回起動時のアプリ説明のために使用。
shared_preferences
ローカルにデータを保存するために使用。
fcm_config
プッシュ通知実装のために使用。Firebaseとfcm_configで比較的簡単にプッシュ通知を実装できました。

アプリの詳細

初回起動時の説明

アプリの初回起動時に,アプリの概要を簡単に説明しています。このために用いたのがintroduction_screenです。またshared_preferencesを使用してローカルに初回起動かどうかを判別するためのbool値を保存させています。

説明画面

新規登録&ログイン

firebase_authを使用すると,メースアドレス・電話番号・Googleアカウント等を使ったログイン機能を実装することができます。

ログイン周りでリジェクトされる要素
  1. ログアウト状態でも一部の機能を使用できるようにしなければならない
  2. TwitterやGoogleなどのサードパーティーのログイン機能を付ける場合に”Sign in with Apple”も実装しないといけない。

1が理由で最初にリジェクトされる方が多いと聞いたのでここは注意しながら開発をしていました。
2については,サードパーティーのログイン機能を付けずにシンプルにメールアドレスでのログイン機能に限定しました。

入力

入力はなるべく簡単にするために,ユーザーにテキストを入力させずにボタンをタップさせたりリストから選ばせるような工夫をしました。

入力画面1 入力画面2

右側の時間を選択するモーダルについては
showModalBottomSheetCupertinoPickerを組み合わせて作成しました。

https://note.com/hatchoutschool/n/n609f84bdd9e6

ランキングの実装

ランキング

Firestoreから選手の情報をgoal(ゴール数)の降順に取得。

    final snapshot = await FirebaseFirestore.instance
        .collection("team")
        //省略
        .orderBy('goal', descending: true)
        .get();
  }

ListView.builderでindexを取得しながら表示。

 ListView.builder(
        itemCount: rankingList.length + 1,
        itemBuilder: (context, index) {
          //各ユーザーのUIを書く
        },
      ),

グラフの描画

グラフの描画にはcharts_flutterを使用しました。以下に様々なグラフの作り方が載っているので参考にしてみてください。
https://google.github.io/charts/flutter/gallery.html

BarChart PieChart
グラフ1 グラフ2

作戦ボードの実装

作戦ボードの実装のためにGestureDetectorのonPanUpdateを使用しました。

 GestureDetector(
        onPanUpdate: (DragUpdateDetails details) {
           _currentPositionX = details.localPosition.dx;
           _currentPositionY = details.localPosition.dy;
        },

opPanUpdateにより上記のように絶対的な座標や相対的な座標を取得することができます。これを応用することで作戦ボード内のマーカーを動かすことができました。

作戦ボード

onPanUpdateについては以下の記事がとてもわかりやすいです。
https://note.com/hatchoutschool/n/n4f70764cc83b

プッシュ通知の実装

以下の記事を参考に比較的簡単に実装することができました。
https://zenn.dev/rafekun/articles/ef8a22f9fe90bd
通知設定については以下の公式ドキュメントが丁寧でとても参考になります。結局一次情報が大事なのよね~と実感。
https://firebase.flutter.dev/docs/messaging/apple-integration/

実装内容:試合結果入力時にチームメンバーにプッシュ通知を送る。
通知内容は「●●と試合がありました!」的な感じで送る。
チームで一つのアカウントを共有してもらっているので,そのアカウントにログインできるユーザーに対してプッシュ通知を飛ばします。

流れとしては

  1. ログイン時に端末のtokenをFirestoreのteamコレクションに追加
  2. 試合結果を入力(create)
  3. 試合結果入力をトリガーにCloudFunctionsの関数が呼ばれ,各tokenにプッシュ通知を送る。

まとめ

様々な記事やドキュメント、これまでエンジニアとして関わってくれたみなさんのおかげでリリースまでに至ることができました!ありがとうございます!
開発して終わりではなく,フィードバックをもらいながらどんどん改善してより良いアプリにしていこうと思います!
次回はRiverpodでアプリを開発するゾ

Flutter大学

Discussion