GameWith Developer Blog

GameWith のエンジニア、デザイナーが技術について日々発信していきます。

社内でFlutterを採用しアプリと管理画面を開発した話 #GameWith #TechWith #Flutter

はじめに

GameWithのクライアントアプリチームでリーダーをしているkyamです。
その前は価値検証チームというところで、色々新規サービスの事業検証などを行っていました。

先月、Flutterで作成したポケGO最新攻略&レイド招待ツールアプリをiOS・Androidアプリでそれぞれ同時リリースしました。

既にGameWithには各ゲームの攻略情報が閲覧できるGameWithアプリが存在するのですが、今回は特定のゲーム(ポケモンGO)で特定の機能(最新の情報やイベントを記事や通知で都度お知らせする機能)に焦点を当てた、MVP的なプロダクトとしてユーザーに提供を行いました。今後のユーザーの反応や得られるフィードバックによって新機能の追加や改善を検討していく流れになります。

今回はこのようなアプリをなぜFlutterで開発したのか、またどのような技術・設計を用いて開発したのかを簡単に共有しようと思います。
これからFlutterでアプリやWeb開発などにチャレンジしようと思っている方の参考になれば幸いです。

今回紹介したいこと

  • GameWithがFlutterを積極的に活用し始めていること
    • 今後もMVPをしっかり定義した上で、素早く価値検証を行うために積極的にFlutterを用いて新規アプリや新規攻略ツールなどを開発していく予定です
  • 今回採用した技術・設計に関して
    • 今回利用した技術やFlutterの設計に関して簡単に紹介させてください

GameWithのFlutter活用に関して

今回このポケGOアプリと管理画面をFlutter x Firebaseで実装しましたが、Flutterを採用した理由としては3点あります。

1点目の理由(開発スピードの向上)

新規でMVPのアプリを作る上でSwiftやKotlinといったネイティブ固有の言語で開発を進めても勿論良いのですが、Flutterであれば複数のエンジニアで一つのプロダクトだけに向き合うことができるのでリソースが集中できるのと、エンジニア間での技術面でのコミュニケーションも取りやすくなり開発スピードが今のGameWithのクライアントアプリチームの体制(少人数)であれば上がると考えました。

2点目の理由 (プロダクトとの相性)

プロダクトとの相性と書いたのですが、FlutterアプリはあくまでもFlutterアプリなのでUIKit風のデザインに寄せたいとか、iOSネイティブやAndroidネイティブを超えるようなUXを提供したいとかだとそこの労力を割くのは少し微妙かもしれません。

見た目や操作の面でFlutterアプリでネイティブアプリと遜色ないものは作れますし、開発効率化などが今回Flutterを採用した目的でもあるので、そういった点も踏まえて今回は相性が良いなと考えました。
(素早くMaterial DesignでFigmaを用意してくれたデザイナーさんにも大感謝です)

今回開発したアプリ(+管理画面) が特に各OS特有の複雑な機能などもなかったので、ホットリロードを使ったUI構築の快適さなど、開発体験で恩恵が得られるFlutter開発が良いなというのも大きいです。

3点目の理由 (チームのモチベーション向上)

最後にこれが内心一番大きな理由でもあるのですが、自分も含めてチームメンバーがFlutter開発にずっと挑戦したがっていたというのが大きいです。 勿論1点目、2点目に上げたように前提としてFlutterを採用することが是であるという判断があってこそではあるのですが、技術的にやりたいことにチャレンジできるというのはエンジニアにとってかなりモチベーションに繋がると思うのでその点も含めて今回採用できて良かったです。

自分は4年前に執筆した下記記事の最後に、今後やりたいことの中でFlutterをやりたいと言っていたので4年越しに社内で実現することができました!笑 tech.gamewith.co.jp

アプリと管理画面の機能に関して

まずアプリと管理画面で提供している機能から簡単に紹介させてください。
今回提供している機能一覧は下記になります。

アプリ

  • 記事データを取得して表示
    • 都度不要な通信をなくすため記事読み込み時にDBに保存
  • 通知(お知らせ)を取得して表示
    • 通知の既読管理
  • WebページをWebViewで表示
    • GameWithの特定の攻略ツールも合わせて利用して欲しいため

管理画面

  • Firebase Authを用いた認証機能
    • VPNでの接続など任意のIPでしか表示できないように
  • アプリに表示するためのお知らせの登録(予約投稿可)・編集・削除機能
  • Firebase Storageへの画像のアップロード
  • 画像のトリム機能(指定箇所を16:9にトリムできるように)

上記を素早く実現するためにバックエンドに関しては積極的にFirebaseを活用し、Firebase AuthenticationCloud FirestoreCloud Storage for FirebaseFirebase Hosting といった機能を採用しています。

過去にVue.jsFirebaseを利用して管理画面を作成した経験があるのですがその時の記事も下記で見られるので少し古いですが良かったら見てください!

tech.gamewith.co.jp

技術設計に関して

Flutter開発でまず悩ましいのが状態管理の方法ですが、今回はアプリ・管理画面共にRiverpodを採用しています。

riverpod.dev

公式ドキュメントにもあるように、状態管理に関しては様々な方法が選択肢として挙げられていますが、日本では近年採用事例が多く、トレンドでもあるRiverpodを使った設計パターンを採用しています。

Riverpod x freezedといった構成です。

この時の設計方針は、かなりネイティブの時の考え方に寄っていたのでMVVMに近い実装をしています。 管理画面などは操作フローに応じて必要なStateを保持したStateNotifierを継承したクラスとProviderを作り、View側ではそれをwatchするといった形です。

Flutter開発ではあまりMVVMViewModelといった設計方針はRiverpodを使った場合、少し冗長であったり、本来のRiverpodを使った設計意図とは微妙にずれてくるとは思いますが、この時はViewModelに近い方法で実装していました。

Riverpodを使った設計方針に関しては、日々色々な会社の技術ブログを読ませていただいたり、直接情報交換させていただいたり、下記の海外の記事を参考にさせていただいたりして検証をしています。

codewithandrea.com

プロダクトやチームに合った設計方針が大事だと思うので一概にこれが正解!というのは無いと思うのですが、今後もFlutterを用いた開発をどんどん推進してくのでクライアントアプリチームとして一旦の設計方針のスタンダードを作るのが今後の目標であり課題です。

開発環境と本番環境について

アプリも管理画面も基本的に同一のFirebase Projectを参照しています。

FirebaseのProjectはRelease, Developmentの2つを用意しており基本的に開発はDevelopmentで進行しています。 環境分けに関しては、flavorを利用しておりビルド時やFirebase Hostingへのデプロイ時は下記を実行する形になります。

・build

flutter run -d chrome --web-renderer html --dart-define=FLAVOR=dev
flutter run -d chrome --web-renderer html --dart-define=FLAVOR=prod

・deploy

flutter build web --release --web-renderer html --dart-define=FLAVOR=dev
flutter build web --release --web-renderer html --dart-define=FLAVOR=prod
firebase deploy

本番環境や開発環境といった複数のプロジェクトを同じプロジェクトディレクトリに関連付ける場合は、プロジェクトエイリアスの機能を利用します。
詳しくは下記のFirebase CLIのリファレンスをご確認ください。 firebase.google.com

終わりに

今回のプロダクト開発で培ったFlutterの知見を元に、現在新たに別の攻略ツールをFlutter Webで開発しています。 社内では常にユーザーがゲームをする上で便利なツールのアイデア出しや開発を行っているのですが、その一環のものです。

今回紹介したアプリよりも開発規模は大きく、色々な技術を採用しているのでリリースできたらまたブログにさせていただこうかと考えています。 もし何かGameWithのFlutter開発や、それ以外でも質問があればいつでもDMください!

twitter.com

ここまで読んでくれて、ありがとうございました。