📱

Pintアプリの開発にFlutter + Firebaseを採用した理由とその結果

に公開

背景

2021 年 12 月ごろ、Pintの企画が完成に近づき、UXの要求がまとまりつつありました。

企画のユースケースを実現するためには慣れた Rails+Webview で構築するのが一番手っ取り早いですが UX があまり良くないので、ネイティブで構築するという方向性で検討を進めました。

アプローチ

速く、安く作るには iOS と Android 上で動作するクロスプラットフォーム対応のフレームワークを採用することが第一候補となります。

当時は、React Naive、IONIC Framework, Cordova などのフレームワークが存在していました。
どれも一定のプロダクションのアウトプットは出せる感じがありました。しかし、開発者の定着度合いがあまり良くなかったり、微妙な UI があるためこの中から選ぶのはあまり良くないなという感覚がありました。

そして、当時は Flutter 2.8 がリリースされたあとでもあり、かなりいろいろなコンポーネントがリリースされてきて Flutter で作られたアプリケーションがちらほら出だしてきているときでした。

また、
【初アプリ】未経験がFlutterで肉牛繁殖農家のためのアプリを作ってみた
というアプリが1ヶ月ぐらいの開発で良さそうなUIのアプリがリリースされていました。これを見て、Flutterのポテンシャルがかなり高く、ユースケースも実現できそうというのはなんとなく感じてました。

新技術を使うときやフレームワークに乗る時にはやはりリスクが伴うので、カルチャーである Fail&Learn の考えのもと、薄く広く実装をしながら Flutter を学習しつつ実現したいユースケースを達成できるかというフィージビリティチェックも同時に進めていきました。

また、アプリ開発においてはフロントエンドとバックエンドの両方の技術選定を決める必要があります。
そして、スタートアップなので速く、安く、持続可能な技術でプロダクトをデリバリーする必要があります。

もっと抽象的に作れるかを検討

Flutter より上位のレイヤーでノーコードに近い形でアプリを開発できたら良いなと思い、まずは FlutterFlow を検討してみました。

FlutterFlowはノーコードでFlutterアプリを構築できるというのが特徴です。デモのUI/UXもすごい良さそうに見えました。

サンプルが豊富にあることや、UI からアプリのコードを生成できる機能があるため、アプリの基本形を作るまでのスピードは非常に速く、プロトタイプ作成などで特に有効なツールかと感じました。また、毎週のように新機能が追加されており、活発なプロダクトであったことも印象的です。

とりあえず使ってみないとわからないので FlutterFlow をベースに開発を進めていましたが、手が届かないと感じる点も出てきました。
FlutterFlow にカスタムのメソッドを適用する機能もありますが、あくまで UI の何かの操作がトリガーのものに限定されるなど、カスタマイズ不能な範囲がどうしてもあります。
例えば郵便番号のバリデーションのようにユーザーが入力中に動いてほしいものや、複雑なユーザーのルーティング条件が必要な場合には対応できないユースケースがありました。

そういったケースは、FlutterFlow から出力したコードを変更して対応します。
FlutterFlow からはソースコードに 1 方向でしか変換できないため、結局のところソースコードを書きかえていくと FlutterFlow 上の UI に差分が出つづけ、マージが手間になリます。

また、FlutterFlow だけでは本番・ステージングなどの複数環境の切り替え機能がないことも、CI/CD など環境を構築するに当たって重要な要件を満たせないこともわかりました。

こうした点を踏まえ、FlutterFlow の利用は諦めました。

Flutter上でDartを書くことに決定

FlutterFlow を使うときに、簡単なアプリであれば問題ないのですが、ちょっとはみ出たことをしようと思うとどう FlutterFlow を使って実現すれば良いのか、ドキュメントも少ない中で考える必要があります。

一方 Flutter は公式ドキュメントが非常に充実しており、結局 0 から開発するほうが自由度高く、かつ早く開発できました。これはローコード・ノーコードツール全般に言えることだと思いますが、ビジネス要件がきっちり決まっている場合は、実現できることをツール側に寄せる必要のある開発スタイルではなく、フルスクラッチで開発するのが良いと思っています。

また Flutter はウィジェットを組み立てて構築していくフレームワークなので、UI からアプリを組み立てていくことにこだわらなくても十分問題ないという言語特性もあります。

ソフトウェアアーキテクチャ選定

Flutter で構築する際に、重要になるのがソフトウェアアーキテクチャのモデル選定です。当時はデファクトスタンダードが無く、どれも一長一短ではありました。主に以下のアーキテクチャがオプションとしてはありました。

  • Stateful ウィジェット
  • MVC
  • MVVM
  • MVVM + repsitory

当時のトレンドの 1 つであった flutter-architecture-blueprintsをベースに、MVVM + repository の構成で設計を進めました。MVVM + repository に関する情報が Web に充実しておりまた最後発で様々なアーキテクチャ上の課題を解決しているためです。

利用したパッケージの紹介

今回、利用したパッケージの一部を紹介します。

riverpod + Flutter Hooks

状態管理には riverpod + Flutter Hooksを使用しています。
freezed
Model を copyWith でイミュータブルに扱ったり、JSON の de/serialize したりといったコードの自動生成をするために使用しています。

flutter_gen

flutter_gen
画像などのリソースファイルへ安全にアクセスできるようにするため使用しています

search_choices

search_choices
銀行口座を一覧から選択する際に、多数の項目から選択する UI が多いです。こちらのパッケージを使用することでテキスト入力からリアルタイムにフィルタリングして項目を絞れ込めます。

バックエンドの選定

バックエンドは Firebase を採用しました。

Amplify なども検討しましたが、やはり Flutter と同じ Google が開発しているので、ドキュメント・パッケージともに Firebase との接続がサポートされているケースが多いです。
また JSON で様々なデータが扱えたり機能ごとにきちんと結びつきがあったりと親和性が高いです。

Flutter を使って開発する場合はバックエンドを Firebase で構築するのがデファクト・スタンダードのような印象を受けました。
Firebase 上の処理が多くなってくるとコストが嵩んでくる問題はありそうでしたが、そのときには適宜バックエンドの再選定をしていくのが良いと思います。

Tips

Flutter で開発をしてみて、得られた知見をまとめておきます。

DartやFlutterの最新情報は要チェック

Dart や Flutter はマイナーバージョンの更新でも大きな仕様変更が入ります。
例えば、2022 年 5 月の Dart2.17 です。enhanced-enum という、enum の拡張機能が追加されたのですが、こちらが release されるまでは enum を自ら拡張して実装する必要がありました。
新興言語ということもあり、大きなアップデートが多いため、変化が多くて楽しいです。

アーキテクチャありきでなくても良い

FlutterFlow から切り替える際にはアーキテクチャから検討を始めましたが、まずは標準的な Stateful ウィジェットでの開発で進めても良かったかもしれません。

というのも、多くのパッケージにおけるサンプルは Stateful ウィジェットで記載されているため、riverpod + Flutter Hooks を軸にしてしまうと、慣れるまでは置き換えるプロセスで手間がかかります。
特に Flutter 未経験の状態であったこともあり、なおさら標準スタイルで進めた方が結果的にリリースまでのスピードが速かったのかなと感じることがあります。
もちろん自社のリソースの技術スタックによりますが、まずは素直に Flutter の公式ドキュメントをベースに進めていくのが一番の近道かもしれません。

最初からきちんとデザインする

デザイナー不在もあり、今回の開発では未経験者の PdM が Material Design 等を無視してデザインをしましたが振り返ってみれば、Material Design を学んでもらって、それに則った開発をするべきだったなあという公開があります。それをすればテーマを当てるだけでよくなるのでコードが軽量化され実装面でも楽になります。

学習コストはかかりますが、トータルで考えたときにペイするので、デザイナーがいない状態でも最初から Material Design に則って設計するべきだと思います。

もちろんエンジニアも Material Design を理解しデザインを作る人とコミュニケーションを取れるようにすることが重要です。

終わりに

Flutterを採用してどうだったか?

回り道もありましたが、総じて Flutter を採用したことは非常にプラスだったと感じています。
結果的にネイティブ開発の知識はビルドなどに関する設定が必要だった程度で、今回のチームでも無事に Android/iOS ともにストアへのリリースまで進めることができました。

実際に開発してみたところ、Native で書くところはほとんどなく、Swift + Kotlin より早く、楽に開発できました

Pint のアプリをリリースしてから半年が経ち、Flutter の勢いは当時よりも増しているように感じます。現時点では Pint アプリは今後も Flutter で開発、運用を続けます。

Pintについて

Pint はアプリを経由するだけで Amazon や楽天などの EC サイトでのお買い物でポイントがもらえるサービスです。この機会にぜひインストールして活用してみてください!

株式会社マインディア テックブログ

Discussion