本書は、データモデル設計、NoSQLデータベース、Firestoreについて学び、FirebaseとFlutterを使用したレストランレビューアプリの開発を通して、スマホアプリ開発の一連の流れをハンズオンで習得することを目的としています。
近年のデジタル化の加速により、安価で使いやすいオンラインサービスへの需要が高まっています。また、昨今では生成AIの進化が目覚ましく、プログラミングにおいても、AIと対話しながら素早くプロトタイプを開発する「バイブコーディング」や、要件を詳細化することでAIが設計からコーディングまでを自動生成する「仕様ドリブンコーディング」といった新たな開発手法が注目されています。これらの手法は開発効率を飛躍的に向上させる可能性を秘めていますが、一方で課題も存在します。
例えば、単純な機能であればバイブコーディングは強力なツールとなりますが、アプリの仕様が少しでも複雑になると、データ構造や画面遷移の整合性が失われ、手戻りが発生するケースが少なくありません。また、仕様ドリブンコーディングにおいても、人間の直感とは異なるデータモデリングや画面設計のギャップに直面し、AIへの的確な指示出しに悩むことがあります。これらの課題の根底には、システムデザイン手法の難しさや、人間中心設計の誤解からデータモデリングの理解が不足しているという共通の問題があります。さらに、従来のプログラミング教育が汎用的なアプリケーション開発に繋がりにくいという課題も指摘されています。
そこで本書では、生成AIを最大限に活用し、かつ手戻りを最小限に抑えながら高品質なアプリを開発するために不可欠な、データモデル設計と画面設計の基礎を徹底的に解説します。エンジニアだけでなく顧客企業の担当者やプロジェクトマネージャも、ユースケースからデータモデルに落とし込む考え方、データモデルから画面設計を行う考え方、そしてこれらのパターンを理解することが重要だと強調しています。前半部分ではデータモデリングの具体的な方法と思考法を詳しく解説し、後半では効率的で汎用的なツール(FlutterとFirebase)のハンズオンを提供しています。
本書を通して、ものづくりに興味を持ち、自身でシステムを構築するマインドを育むことで、IT技術の活用が民主化され、より価値のあるオンラインサービスが世に増えることを著者は願っています。
本書で学べることは以下の通りです。
Copyright 2025 RISA Co., LTD.
データモデル設計は、まずユースケースからデータの候補を抽出することから始めます。これによってデータの大きな単位とそこに含まれるフィールドを整理できます。また、ここで抽出されたデータ単位ごとに具体的なデータサンプルを作っておくと、次ステップのデータ間の関係を考察する際に役立ちます。
データ候補が抽出できたら、まとめたデータサンプルを参照しながらそれらの関係を整理します。本書ではドキュメント型データベースを採用するため、ドキュメントとコレクションの関係を整理します(ドキュメント型データベースについては、「NoSQLとFirestoreについて」を参考にしてください)。前ステップで行ったデータ候補の抽出は比較的簡単な作業ですが、ここで行うデータ間の関係整理は経験が必要な難しい作業です。前ページ「はじめに」で述べたように、アプリの仕様が複雑になった際に生じる手戻りや、データモデリングと画面設計のギャップといった課題も、このデータ間の関係整理の難しさに起因すると考えられます。 次ページ「ユースケース、データモデルと画面設計のパターン」では、よくあるユースケースとデータモデルと画面設計のパターンをまとめていますので、興味がある方はそちらを参照ください。
コレクションとドキュメントの分離方針が決まったら、サンプルデータをJSON形式で表現します。JSONスキーマに沿った正しいJSON形式にまとめることで、ドキュメント型データベースで扱えるサンプルデータが作成されます。JSONはWebアプリケーションやREST APIで扱われる、プログラムが処理しやすく人も見やすいデータ形式ですが、初めてJSONを扱う人は正しいJSON形式とは何かわからないかもしれません。そのため本書では、本文中にJSONエディタというツールを組み込んでJSONデータを表示し、JSON形式でのサンプルデータの作り方をステップバイステップで解説します。
顧客がレストランに対して星の数とコメントでレビューを記入し公開するアプリを例に、ユースケース記述を以下にまとめます。アプリ名は「レストランレビューアプリ」とします。
このユースケース記述から得られるデータ候補を「ドキュメント(フィールド1、フィールド2、‥)」と表現すると、下記のように整理できます。
ここで具体的なサンプルデータを表形式にまとめておくと、イメージがしやすくなり、今後の設計もスムーズに進みます。また、開発メンバーへの説明にも役立ち、開発やテストなどにも活用できます。
表1. レストラン
ID | 店名 | 種類 | 住所 | 星数 | ロゴ |
0 | ガスト東岡崎店 | 洋食 | 愛知県岡崎市大西1丁目1−10 | 0 | https://www.skylark.co.jp/site_resource/gusto/images/logo.svg |
1 | デニーズ東岡崎店 | 洋食 | 愛知県岡崎市美合町 字五反田25-1 | 0 | https://sozainavi.com/wp-content/uploads/2019/10/dennys.jpg |
2 | 大戸屋ごはん処岡崎店 | 和食 | 愛知県岡崎市井田西町1−11 | 0 | https://sozainavi.com/wp-content/uploads/2019/10/ootoya.jpg |
3 | 和食さと岡崎店 | 和食 | 愛知県岡崎市上里2丁目1−1 | 0 | https://sato-res.com/assets/tile/sato.png |
4 | カレーハウスCoCo壱番屋岡崎上地店 | カレー | 愛知県岡崎市上地3丁目51−6 | 0 | https://www.ichibanya.co.jp/assets/images/common/ogp.png |
5 | スシロー岡崎上和田店 | 寿司 | 愛知県岡崎市天白町東池15−1 | 0 | https://www.akindo-sushiro.co.jp/shared/images/ogp.png |
6 | くら寿司北岡崎店 | 寿司 | 愛知県岡崎市錦町2−12 | 0 | https://asset.watch.impress.co.jp/img/ipw/docs/1230/499/kura1_s.jpg |
7 | モスバーガー岡崎大西店 | ハンバーガ | 愛知県岡崎市大西1丁目16−7 | 0 | https://www.mos.co.jp/mos_ogp.png |
8 | マクドナルド岡崎インター店 | ハンバーガ | 愛知県岡崎市大平町石丸60−1 | 0 | https://sozainavi.com/wp-content/uploads/2019/10/mcdonalds.png |
9 | かつや愛知岡崎インター店 | とんかつ | 愛知県岡崎市大平町新寺25 | 0 | https://www.arclandservice.co.jp/katsuya/wp-content/themes/arclandservice-group/assets/img/katsuya/common/logo.svg |
表2. レビュー
レストラン「ガスト東岡崎店」に対するレビュー
ID | 顧客名 | 星数 | コメント |
0 | 鈴木一郎 | 2 | 値段の割に合わない気がする。 チーズハンバーグを頼んだが、レトルトな感じでした。 さらに、スープセットにしたが、スープは一種類。 |
1 | 佐藤二郎 | 3 | タブレットによる注文に変わったが、慣れが必要。 メニューを広げて、料理を比べたい。 この方式で価格が下がればよいが、,, |
2 | 北島三郎 | 5 | ドリンクバーが99円(単品で注文してもOK)。 パソコンの持ち込みOK。 コンセントで充電できる。持ち帰り容器は無料。 食べきれない料理の持ち帰りOK。 トイレは新しくてキレイ |
表3. 顧客
ID | メールアドレス | 氏名 | アイコン |
0 | ichiro@test.com | 鈴木一郎 | https://meikyukai.jp/wp-content/uploads/2020/06/51_ichiro.jpg |
1 | jiro@test.com | 佐藤二郎 | http://www.from1-pro.jp/images/t_10/img_l.jpg?1597426029 |
2 | saburo@test.com | 北島三郎 | https://cdn.asagei.com/asagei/uploads/2016/08/20160810kitajima.jpg |
1で抽出したデータをもとにドキュメントとコレクションの関係についての方針を整理します。
これらの関係を表現したツリー構造を下図に示します。
ドキュメントとコレクションの関係について方針が決まったら、1のサンプルデータをJSON形式であらわすことでより具体化します。本書ではブラウザ上で利用できるJSONエディタを使い、段階的にサンプルのJSONデータを作成します。
上記表1のIDが0のレコードを参考にレストラン・ドキュメントを作成します。
JSONではデータのひとつの塊であるドキュメントを { } で囲み、その中に "属性名": "属性値" をカンマ( , )で区切ってリストします。
上記表1の通りレストランは10個存在するため、配列をあらわすコレクションとして表現します。
JSONではこのコレクションを { "配列名": [(ドキュメントをカンマ( , )で区切ってリスト)] } で表現します。
レストランと同じく顧客コレクションもルートレベルに追加します。
JSONでは二つのコレクションを { "users": [(...)], "restaurants": [(...)] } と表現します。
レビュー・ドキュメントの配列であるコレクションをレストラン・ドキュメント配下に追加します。この時、レビュー・ドキュメントには書き込みを行った顧客がわかるように顧客IDと顧客名と顧客写真を追加します。また、レビュー・ドキュメントを参照するだけで書き込みを行ったレビュー対象のレストランがわかるよう、レストランID、レストラン名、レストランロゴといった項目も追加します。以上の作業の必要性については「NoSQLとFirestoreについて」を参照してください。
Copyright 2025 RISA Co., LTD.
データモデルの設計が完了したら、次にユーザーインターフェース(UI)の「画面」と「画面遷移」をデザインする「画面設計」に進みます。
画面設計においては、大きく分けて「画面」と「画面遷移」の二つの要素をデザインします。
「画面」はユースケースによって多様な種類が存在するためパターン化が難しいですが、「画面遷移」は以下の4つの主要なパターンに分類できます。これらのパターンを理解することで、効率的かつ一貫性のある画面遷移を設計できます。
このパターンは、アプリケーションが複数の独立した機能を持つ場合に適しています。ホーム画面にメニューやナビゲーションバーを配置し、ユーザーがこれらを選択することで、異なる機能画面へ切り替えます。
スマートフォンは画面が小さいため、多くの情報を入力する必要がある場合にこのパターンが有効です。アンケートや申請書のように、複数の画面に分けて入力を促し、最終的に確認画面を経てデータを送信する形式の画面遷移です。
アプリケーションの内部的な「状態」に応じて表示される画面が変化するパターンです。ユーザーがログインしているか、ログアウトしているか、あるいは特定のタスクのどの段階にいるかといった状態変数の値に基づいて、適切な画面を表示します。
ビジネスアプリケーションで最も頻繁に用いられるパターンです。複数のデータを一覧表示(Read)し、その中から一つを選択して詳細を表示(Read)し、さらにその詳細を編集(Update)したり、削除(Delete)したりする機能を提供します。データの追加(Create)もこのフローに組み込まれます。
本書で開発する「レストランレビューアプリ」の画面設計を、前述の基本的な考え方を基に、以下の4つの主要なフローにわけて説明します。これらのフローは、アプリの主要機能とユーザーの操作体験を網羅しています。
①ログイン、メニュー選択、ログアウト
このフローは、ユーザーの認証とアプリの主要機能間のナビゲーションを管理します。
②レストランリストとレストラン詳細、レビュー表示とレビュー追加
このフローは、レストラン情報の閲覧と、特定のレストランへのレビュー投稿に特化しています。
③全レビューリストとレビュー表示
このフローは、アプリに投稿された全てのレビューを横断的に閲覧するためのものです。
④アカウント表示と自分が投稿したレビューの管理
このフローは、ユーザー自身の情報管理と、自分が投稿したレビューの個別管理に焦点を当てています。
Copyright 2025 RISA Co., LTD.
様々なアプリケーション開発で活用できるユースケース、データモデル、画面設計のパターンを紹介します。特に、頻繁に利用される特徴的な機能や、一般的なアプリのユースケースを例に挙げ、その設計思想を解説します。経験の少ない開発者でも自身のユースケースから適切なアプリ設計を行えるように、既存のパターンを理解し、参考にすることを目的としています。
一般的なビジネスアプリケーションの多くは、ログインしたユーザーの権限に基づき、複数データを整理・管理することを目的としています。これらは「画面設計の基本的な考え方」で紹介した画面遷移パターンの組み合わせでほとんど対応可能です。
しかし、以下の機能は特有の画面を持つことが多いため、個別のパターンとして覚えておくと有用です。
① ID&パスワード・ログイン
② パスワードレス・ログイン
③ チャット
④ スケジュールとカレンダー
⑤ 地図
⑥ 決済・ポイント支払
⑦ イラスト・写真加工
⑧ OCR・物体認識
一方、ゲーム、AR(拡張現実)、スマートスピーカーといったアプリケーションは、複雑なUIや音声によるUIで構成されるため、一般化が難しく、本書の対象外とします。
ユースケース
ユーザーが思いついたことや覚えておきたい内容を記録するための基本的なメモアプリのユースケースを以下に記述します。ここでは、メモの共有や手書きメモのテキスト変換といった高度な機能は含まず、基本的なメモ機能に焦点を当てます。
データモデル
このユースケース記述から得られるデータ候補を「ドキュメント(フィールド1、フィールド2、...)」と表現すると、下記のように整理できます。
画面設計
メモアプリの画面設計は、「リストと詳細のCRUD」パターンを基本とします。
ユースケース
大学の学生名簿を管理するアプリのユースケースを記述します。
データモデル
画面設計
「リストと詳細のCRUD」パターンと「状態遷移(管理者/学生)」パターンを組み合わせます。
ユースケース
地域の観光地を紹介するアプリのユースケースを記述します。
データモデル
画面設計
「リストと詳細のCRUD(参照と一部更新)」パターンと「検索/フィルタリング」機能を組み合わせます。
(TODO)
(TODO)
(TODO)
(TODO)
(TODO)
(TODO)
(TODO)
(TODO)
(TODO)
(TODO)
(TODO)
(TODO)
(TODO)
(TODO)
(TODO)
(TODO)
Copyright 2025 RISA Co., LTD.
ここでは画面設計に関連して、スマホアプリのUIデザインについて記述します。世の中のスマホといえば、iPhoneとAndroidの2種類ですが、それぞれAppleとGoogleがUIデザインのガイドラインを出しています。iPhoneはヒューマン・インタフェース・ガイドライン、Androidではマテリアル・デザインです。各ガイドラインの紹介をする前に、スマホアプリ特有の問題からデザインの歴史を説明してから、ヒューマン・インタフェース・ガイドラインとマテリアルデザインの紹介をします。
スマホには、パソコンとは異なる2つの特徴があります。
画面が小さく操作手段が限定的
スマホは画面が小さくさらにマウスやキーボードがないため操作手段が限定されるため、画面レイアウトや操作方法をどのようにデザインするかでユーザ満足度が大きく変化します。
画面サイズがばらばら
AndroidとiPhoneという違いだけでなく、同種のスマホでも画面サイズが様々で、アプリのレイアウト幅や高さを固定すると画面表示が崩れて使い物にならなくなります。例えば、歴代のiPhoneを比べても下図のとおり様々な画面サイズが存在しますし、Androidは各デバイス開発会社が様々なものを出しているのでiPhone以上に画面サイズはバラバラです。
Google PlayやApp Storeに登録された実際のアプリの評判からまとめたスマホアプリに対するよくある悪評は主に以下の4つに集約されます。
これらの悪評のうち、1以外の2から4まではUIデザインの問題といえます。
それではスマホにおけるデザインはどのような歴史を歩んできたのでしょうか。
まず、2000年前半のWebやアプリケーションのUIはそれまでのWindowsパソコンが機械的で使いづらく利用者のことを考えて作られていないという反省から、現実世界を模した装飾的なデザインからなるUIを取り入れるようになりました。この考え方によるデザインをスキューモーフィズムと呼びます。ただし、この装飾に凝ったデザインでは、デザイナーの主張が先行し、見た目や操作性に統一感がないといった弊害を生むことになりました。
そのため、20世紀初頭にモダニズムが建築や工業製品のデザインに取り入れられたように、パソコンやWebやスマホのデザインにも極力装飾を廃したフラットデザインが採用されることになりました。このフラットデザインを採用しているのがAppleです。AppleはiPhone 7のデザインにフラットデザインを取り入れ、ヒューマン・インタフェース・ガイドラインもそれにのっとったガイドラインを発表しています。
iPhone6のスキューモーフィズム | iPhone7のフラットデザイン |
しかし、フラットデザインはシンプルすぎて、システムの構造やしくみが理解しづらいといったデメリットが挙げられます。そこで、Googleはフラットデザインとスキューモフィズムの中間をとり、さらに発展させた「マテリアル・デザイン」を定義し、2014年にだれもが参照して利用できるオープンソースな形でデザインガイドラインを発表しました。
本書では、ヒューマン・インタフェース・ガイドラインの概要を述べるものの、マテリアル・デザインをメインに説明します。また、本書で利用している開発プラットフォームであるFlutterもマテリアルデザインを全面的に採用しており、AndroidはもとよりiPhoneでもマテリアルデザインを実装することができるツールであるため、本書においては開発全般でマテリアルデザインを採用しています。
ヒューマン・インタフェース・ガイドラインでは3つのデザインテーマと6つのデザイン原則とその他設計の詳細が記載されていますが、ここでは3つのデザインテーマと6つのデザイン原則を紹介します。
iOSアプリは「明確であること」「コンテンツにフォーカスすること」「奥行きがあること」の3つのデザインテーマにのっとってデザインすることを推奨しています。
1. 明確であること
あらゆる画面サイズのスマホデバイスで、テキストは読みやすく、アイコンは明快で、装飾は繊細で適度であり、かつ機能的であることが必要です。空間、色、フォント、グラフィック、インターフェイスに関する各要素は、重要なコンテンツは適度に強調されインタラクティブ性を向上します。
2. コンテンツにフォーカスすること
滑らかな動きと鮮明で美しいインターフェースは、ユーザが操作に迷うことなく、コンテンツを理解して操作するのに役立ちます。通常、コンテンツは背景の上に表示されますが、背景を半透明にするなどの工夫で、より多くのことを示唆します。ベゼル、グラデーション、ドロップシャドウの使用を最小限に抑えながら、コンテンツを最優先に表示することで、インターフェイスを明るくわかりやすくします。
3. 奥行きがあること
明確な視覚的レイヤーとリアルな動きが階層を伝え、画面に活力を与え、ユーザに理解を促進します。接触の間隔と発見のしやすさはユーザに喜びを高め、コンテキストを失うことなく機能と追加コンテンツへのアクセスを可能にします。トランジションは、コンテンツをナビゲートするときに奥行き感を提供します。
iOSアプリは、ユーザへのインパクトとリーチを最大化するため、アプリのアイデンティティを強化するため、次の原則に従うことを推奨しています。
1. 美的完全性
美的完全性は、アプリの外観と動作がその機能とどれだけうまく統合されているかを表します。たとえば、ユーザが慎重を期す作業をするアプリでは、微妙で目立たないグラフィックと標準的な操作、予測可能な動作を提示することで集中力を維持できます。一方、ゲームなどの没入型アプリでは、発見を促しながら楽しさと興奮を約束する魅力的な外観を提供するとよいでしょう。
2. 一貫性
一貫性のあるアプリはシステムが提供するインターフェース要素とよく知られたアイコン、標準のテキストスタイル、統一された用語を使用することで、使い慣れた標準的な印象を与えます。このようなアプリはユーザが期待する方法で機能と動作を組み込んでいます。
3. 直接的な操作
画面上のコンテンツを操作することで、ユーザを引き付け、理解を促進します。ユーザは、デバイスを回転させたり、ジェスチャーを使用して画面上のコンテンツに影響を与えたりすると、直接的な操作の体験をします。直接的な操作を通じて、自らの行動が即時にアプリに影響を与えることを体験するわけです。
4. フィードバック
フィードバックは行動を認め、結果を示して人々に情報を提供し続けます。組み込みのiOSアプリは、すべてのユーザーアクションに応答して知覚可能なフィードバックを提供します。インタラクティブな要素をタップすると簡単に強調表示され、進行状況インジケーターが長時間実行されている操作のステータスを伝え、アニメーションとサウンドがアクションの結果を明確にするのに役立ちます。
5. メタファー
アプリの仮想オブジェクトとアクションが、現実の世界に根ざしているのかデジタルの世界に根ざしているのかにかかわらず、身近な体験のメタファーである場合、ユーザはより迅速に学習します。ユーザが画面を物理的に操作するため、メタファーはiOSでうまく機能します。ビューを邪魔にならないように移動して、下のコンテンツを公開します。コンテンツをドラッグしてスワイプします。スイッチを切り替えたり、スライダーを移動したり、ピッカーの値をスクロールしたりします。ユーザは本や雑誌のページをめくることさえします。
6. ユーザーコントロール
iOS全体を通して、アプリではなくユーザが制御します。アプリは一連の行動を提案したり、危険な結果について警告したりできますが、アプリは意思決定をしません。最高のアプリは、ユーザーを有効にすることと望ましくない結果を回避することの間の正しいバランスを見つけます。アプリは、インタラクティブな要素を使い慣れた予測可能な状態に保ち、破壊的なアクションを確認し、すでに進行中の場合でも操作を簡単にキャンセルできるようにすることで、ユーザーがアプリをコントロールしているように感じさせることができます。
一方、マテリアルデザインとは、Googleが2014年に発表したUIのデザインガイドラインです。Googleは、Gmailなどの数多くのアプリを世に出していましたが、それらがパソコン、Android、iPhone、タブレットなど異なるデバイスで利用されるとき、画面サイズもOSも異なるため、異なった見た目と操作性を持ってしまったことを問題視していました。そこで、デバイスが異なっていても、統一したデザインで操作できるようなUIデザインのガイドラインを作る目的で開発されたのがマテリアルデザインです。例えば、スマホのようなデバイス用には、片手で操作することを想定し、直感的で意味のある物理的(マテリアル)な概念をデザインに取り入れてガイドラインが策定されています。また、明示はされていませんが、ユーザ インタフェースという意味では、ヒューマン・インタフェース・ガイドラインで挙げた3つのデザインテーマと6つのデザイン原則は、マテリアルデザインでも目指すところは同じです。
マテリアルデザインは、あくまでもガイドラインであるため、必ず準拠すべきものではありませんが、デザインの部品がどのような形でどのように動くかが細かく規定されており、Java、Kotlin、Swift、JavaScript、Flutterといったさまざまな言語に対応した無料で利用できるプログラムライブラリとともに提供されているため、まるまる採用することで一定レベル以上のUIデザインのアプリを最小のコストで開発することができます。そのため、多くのプロジェクトで採用されるに至っています。
マテリアルデザインは以下の4つのコンセプトからなりたっています。
1. 形をもった面
形をもったうすい紙のような面が重なって画面を表示するしくみを採用しています。この考え方によって、一枚の紙を切って分割して記事を表示したり、メニューやフッターを表示するための紙と中心のコンテンツをのせるための紙が重なって表示されることを影を使って表現することができます。これによって実際は奥行きがなくフラットなスマホの画面を立体的に表現することによって、表示されているものの種類が区別しやすくなったり、高さを使うことで手前にあるものほど重要といったユーザが3次元の世界で感じるのと同じくどこに注意をむけるべきかを直感的に知らせることができるようになっています。
2. 印刷物のようなデザイン
文字や絵が紙に載っているという概念からなり、ベースラインやキーラインといった印刷物のコンセプトを踏襲しています。ベースラインを決めることでコンテンツが収まる範囲を決めたり、本文やタイトルなどはキーラインを基準に配置するなど、印刷用にワードなどに設定する値などを応用することで、見た目に統一感を持たせて画面を美しくみせます。また見やすいフォントが無料で提供されています。
3. 意味のあるアニメーション
ユーザになんらかの意味を伝えるためにはアニメーションが効果的な場合がありますが、コンポーネントにアニメーション表示を簡単にほどこせるようなしくみを実装しています。
4. アダプティブデザイン
パソコン、Androidスマホ、iPhone、タブレットなどデバイスが異なり画面サイズが異なっていても形を崩さず表示するしくみを実装しています。レスポンシブデザインも同じコンセプトですが、アダプティブデザインは横幅の伸び縮みだけでなく、メニューの表示非表示などを含む、より画面サイズに応じた(アダプティブな)形でデザインを変化させるしくみをそなえています。
マテリアルデザインを使うと下記のようなリッチなUI画面を実装することができます。下記リンクを開くとFlutterを使って実装したUI画面のサンプルギャラリーが参照できます。
またFlutterでは、下記のようなマテリアルデザインの部品が提供されています。このように画面にのせる部品はたくさん存在しているので、それぞれ何ができるかだけ覚えておいて、画面パターンに従って使う部品を選別してから詳細の実装方法を調べるのがよいでしょう。
※「レストランレビューアプリ」で利用している部品には「◯」印をつけています。
アップバー ◯ |
| ボタン ◯ |
| カード ◯ | チップ ◯ |
|
| ダイアログ ◯ |
| リスト ◯ |
|
|
|
|
|
|
|
|
|
|
|
|
|
グリッド ◯ | アイコン ◯ | アバター ◯ |
マテリアルデザインではありませんが、「レストランレビューアプリ」で使っている部品を紹介します。
|
|
マテリアルデザインはアプリのブランディングを統一的に進めるためにカラーテーマというしくみを採用し、アプリケーション全体で部品の色やフォントカラーを統一させることが可能です。逆に言うと、同じアプリでもカラーテーマを変えてイメージの異なるアプリとして仕上げることが可能ですので、アプリケーションのテンプレートを先に作っておいて様々なプロジェクトに応用する場合にもこのようなしくみは役に立つでしょう。
カラーテーマ:https://material.io/design/color/the-color-system.html
カラーツール:https://material.io/resources/color/
マテリアルデザインは単なる画面と画面遷移にとどまらず、音声や機械学習に関するUIについても拡張し、ガイドラインを提供しています。
機械学習機能に関するマテリアルデザイン:https://material.io/design/machine-learning/understanding-ml-patterns.html
音声に関するマテリアルデザイン:https://material.io/design/sound/about-sound.html
これらはスマホにかかわらず、スマートウォッチ、スマートスピーカーやスマートイヤフォン、スマートグラスなどにもマテリアルデザインを適用していこうという取り組みのあらわれであり、次章で紹介するFlutterという開発環境も同じ目的で開発が進められています。
2021年5月のGoogle I/OにおいてAndroid12のリリースにあわせてマテリアルデザインの更新がなされています。ここでは、スキューモフィズム的なモノを表現する普遍的なロゴデザインを継承しつつ、高度にパーソナライズすることができ、仕事とプライベートの切り替えが用意でモダニズム的な要素を加えたデザインを目指したとのことです。具体的には、新しいテクノロジーを快適に使えること、デバイスやアプリとの境界線を無くすような慣習に挑戦すること(イコノクラスム)、入力に反応する有機的な動きなど自然界のスピリットを取り入れることを目指しています。また、壁紙の色使いにあわせてパーソナライズされたカラーパレットを適切に自動設定してくれるダイナミックカラーという機能を有しています。今後カラーツール等にもこれらの自動化機能が付与されてくるかもしれません。
このようにマテリアルデザインは、いま世界で最も適切にデザインされ、オープンで誰にでも利用可能で、いまだ活発に進化を続けている生きているデザインシステムといえます。
通常、アプリケーションの開発プロジェクトでは、事前にマテリアルデザインのようなデザインフレームワークからプロジェクトで活用するレイアウトや部品を選択してカラーテーマやフォントを決めて、アプリのブランドに統一感を持たせることをします。このようなデザイン原則とデザインフレームワークの組み合わせを「デザインシステム」と呼びます。
最近日本国内でも「みんなの銀行」や「デジタル庁」でもデザイン原則やシステムデザインを整備してWebサイトを作るといったアプリ開発を行うことがはじまっています。Webサイトといった単純なUIだけならデザインシステムもロゴやカラーデザインや画面テンプレート程度を決めるだけですみますが、スマホアプリのデザインシステムというとより複雑な機能を含みますので、これを一から作るのは大変な労力がかかります。
そのため、本書ではマテリアルデザインをまるまるデザインシステムとして採用してスマホアプリを開発します。サービスのブランディングに関わるロゴやイラスト、カラーデザインをカスタマイズする機能もマテリアルデザインを支えるFlutterのようなツールにも開発が進められていますので、これを使わない手はないでしょう。
Copyright 2025 RISA Co., LTD.
本書では、開発環境にGoogleがオープンソースとして開発しているクロスプラットフォーム開発環境であるFlutterを、インフラ環境にはGoogle Cloud Platform上のモバイル開発用クラウドプラットフォームであるFirebaseを利用します。本章ではこれらを選定した根拠を記載し、ベンダーロックインを排除するための代替案をまとめます。
最近のスマホアプリ開発では「あらゆるデバイス向けにネイティブアプリを開発しメンテナンスをする」か「特定のクロスプラットフォームフレームワークを選択して一つのコードをメンテナンスする」かを選択する必要があると言われています。
「あらゆるデバイス向けにネイティブアプリを開発しメンテナンスをする」を選択しているのは現在スマホアプリをリリースする企業の80%に上り、ネイティブアプリ開発により得られる操作性のよさと引き換えにiPhoneとAndroid用に2つのソースコードで開発し、両プラットフォーム用に卓越したプログラマーを雇い、コストをかけて運用しています。一方「特定のクロスプラットフォームフレームワークを選択して一つのコードをメンテナンスする」を選択する場合、開発されるアプリケーションはネイティブアプリより操作性や機能は劣るが、両方をネイティブ開発するより半分程度のコストですむことになります。
参考)Why choose Flutter for your company?
しかし、Flutterは第三の選択肢として機能します。FlutterはDart言語でプログラミングすると完全にネイティブなiOS用コードとAndroid用コードを生成してくれます。さらにはこれをリアルタイムで行うため、開発したスマホアプリを動かしながらDart言語によるソースコードを修正し、画面を修正することができます(この機能をホットリロードといいます)。このようにFlutterを使うことで、ワンコードで同じUIのiPhoneとAndroid両方のネイティブアプリを開発することが可能になります。
またFlutterを選択することで得られるビジネス上のメリットを以下に示します。
なお、Flutterと比較されるクロスプラットフォーム開発環境と特徴を以下に紹介します。
以上のことを総合的に判断し、Flutterをベストな選択であると考え採用しました。
Flutterのよさだけを強調すると初めての方は少ない知識で何も考慮することなくアプリが開発できると勘違いするとよくないので、Flutterを正しく学ぶためのマインドセットを最後に紹介します。
※ 本記事は下記の動画を参考に作成しました。
https://www.youtube.com/watch?v=kD-1dZBmRPU
本書で開発するレストランレビューアプリもそうですが、世の中のスマホアプリはインターネット上のサーバと連携してサービスを提供します。通常インターネット上のサーバはアプリに入力したデータを保存したり、アプリに表示するデータを提供するデータベースが主要な機能になりますが、スマホアプリからのアクセスに通常のWebアプリが採用しているODBCやJDBCのようなしくみを選択するのはセキュリティ上の理由からも推奨されません。そのため、アプリからのアクセスの際、テーブルへのCRUDのどの機能が必要かを考えてAPIを開発し、さらに認証認可のしくみを実装することが必要になります。
一方、Firebaseは、アプリにログインする認証のしくみ(Firebase Auth)とアプリと安全にコネクションを繋いだままストリーム処理が可能なデータベース(Firestore)、写真などの大きめのバイナリファイルを保存するためのストレージ(Firestorage)といったサービスを提供します。またクライアント用には、Firebase Authで認証されたユーザIDと紐づけてFirestoreデータベースにデータを保存したり、FirestorageのURIをFirestoreデータベースに保存して利用する機能を、様々なプログラミング言語向けに標準的なSDKとして提供されています。そのため、一からバックエンドのサービスを開発するのに比べ、基本的な機能をほとんど開発する必要がないため、開発工数を劇的に削減することができます。
※ Firebase Authにおけるブルートフォース攻撃対策については下記記事を参照してください。
https://medium.com/swlh/google-firebase-authentication-vulnerability-245050cb7ceb
さらには、FirebaseはA/Bテストを行う機能やスマホアプリのクラッシュログを収集する機能、ユーザがどの画面のどのボタンをクリックしたかといった動線を集計する機能、スマホアプリをテストユーザに配布する機能などモバイルアプリ用に豊富な機能を安価に提供しているため、多くのモバイルアプリ開発者に採用されています。
以上の理由から本書ではバックエンドの機能にFirebaseを採用することにしました。
企業におけるITツールの選定で気をつけるべき点にベンダーロックインの排除が挙げられます。というのも、採用技術の開発が止まったり急に利用コストが値上げされ別の方法を模索しなければならなくなったり、アプリを横展開して他社に提供する場合先方のプラットフォームにあわせなければならない、といったことがありうるため、採用時のメリデメだけでなく他に乗り換える可能性も考慮しなければなりません。
まず開発環境としてのFlutterについては、100%オープンソースであり、プロジェクトがストップしたりいきなり有料サービスになることは、いまとなってはまずあり得ないため、Flutterを採用することによるベンダーロックインはありえないと考えてよいでしょう。
一方、Firebaseについてはアプリの横展開をする際にクラウドサービスを使いたくないケースが考えられるので、なんらかの代替案を考える必要があります。Firebaseのサービスごとに代替案を以下に紹介します。
Copyright 2025 RISA Co., LTD.
Googleが公開している12コマの動画シリーズをベースにNoSQLデータベースとFirestoreを解説します。また最後に実践を通して得られたNoSQLの限界について記載します。
ここで紹介する動画シリーズは、GoogleのTodd Kerpelman氏による「Get to know Cloud Firestore」という動画シリーズで、Firestoreを使い始めるにあたって知っておくべきことを12回にわたって解説しているものです。本書に添付された動画は全画面表示が可能ですし、英語の字幕を自動表示する設定になっていますが、英語が苦手な人はYoutube画面の右下の設定で字幕をONにし、さらに字幕の自動翻訳を選び日本語を選択して日本語字幕を表示することも可能です。
Firestoreにおけるルール
Firestoreでは、JSONの構造における配列([]で表す)とマップ({}で表す)をドキュメント型リアルタイム・データベースとしてうまく操作できるようコレクション(JSON内の配列に相当)とドキュメント(JSON内のマップに相当)にうまく分離して保存管理するよう設計します。この設計をうまく行うためにはFirestoreにおけるいくつかのルールを理解しておく必要があります。
ルール1: ドキュメントには制約がある
ルール2: 検索結果はドキュメント全体が出力される
ルール3: 検索対象は浅い
ルール4: 課金はドキュメントの読み書き回数でカウントされる
ルール5: 配列操作は奇妙である
参考)https://firebase.googleblog.com/2014/04/best-practices-arrays-in-firebase.html
ドキュメント型データベースにおいて、ユースケースに適したデータ構造を設計するとき主に以下の3種類の構造から適切なものを選びます。
タイプ1. ドキュメントの一部として配列もしくはマップとして含める
タイプ2. オブジェクトをサブコレクションにおさめる
タイプ3. オブジェクトをルートレベルのコレクションにおさめる
https://cloud.google.com/firestore/docs/concepts/structure-data?hl=ja
https://cloud.google.com/firestore/docs/security/get-started
https://firebase.google.com/docs/reference/security/database
参考)
リアルタイムデータベースの操作について下記の迷信がありますが、Firestoreはこれらの迷信を覆します。そのためFirestoreにおいてはデフォルトでリアルタイム機能を使うよう設計し開発をすすめることをおすすめします。
いいえ。Firestore用SDKがストリーム処理をしてくれるので使い方を覚えれば実装は簡単です。
いいえ。更新された分だけが読み込み数にカウントされ、むしろ全部を読み込む方式の方が課金されます。リアルタイム処理の方が一般的に課金が少なくなります。
いいえ。リスナーを常駐させることは電力消費を増やしません。
https://www.youtube.com/watch?v=DYfP-UIKxH0
Cloud Functionsをどのような場合に利用すればよいか、5つのパターンにまとめると以下の通りです。ただし繰り返しになりますがリアルタイムデータベースのメリットが享受できなくなる欠点があることは考慮すべきでしょう。
最後にいままでのオフィシャル動画とは直接関係ありませんが、Cloud Firestoreが提供するNoSQLのしくみは安全で使い勝手が良くスケーラブルでいいことづくめに見えますが、やはりリレーショナルデータベースにしか表現できないデータモデルというものがあり、NoSQLの限界というものが存在します。例えば、プロジェクトと要員を紐付けたい場合にマッチング値を計算して中間テーブルに持ち、特定のプロジェクトに適した要員をマッチング値でソートしたり、特定の要員に適したプロジェクトをマッチング値でソートしたりすることはリレーショナルデータベースでは可能ですが、NoSQLには構造上できません。NoSQLでこれを実現するには、プロジェクト・コレクションに要員マッチング値という配列項目を用意して、逆に要員コレクションにプロジェクト・マッチング値という配列項目を用意してそれらを使って検索を行う必要があります。この方式の難点は重複してデータを持つことになることとプロジェクトや要員が新規に追加される際にマッチング値を再計算してデータ更新が必要になることです。
NoSQLの利用はプロトタイプ開発などすぐにアプリを開発する必要がある場合にはよいでしょうが、データモデルの機能によっては適さない場合があるので、気をつけるとよいでしょう。
Copyright 2025 RISA Co., LTD.
FlutterはDartと呼ばれる新しいプログラミング言語で実装されており、Dart言語を使ってプログラミングを行います。DartはJavaScriptに似た言語で、Webアプリケーションにおいて必要な非同期処理やストリーミング処理にたけたオブジェクト指向言語です。JavaやJavaScriptなどの言語をマスターした読者であればすぐに学習して使えるでしょう。
ここまでの説明から、アプリケーション開発の基本はデータモデルとアプリ画面のマッピングであることは理解してもらえたかと思います。そのため、アプリ開発においてDart言語が効果的に機能する重要なしくみとしては「1. 認証サービスやデータベースとネットワークごしに非同期でやりとりするデータをうまく処理すること」と「2. 得られたデータ(特にリスト型)を画面表示用にうまく変換すること」といえます。そのため本書では、2のリスト型のデータ変換理解のため「コレクション型」と1の非同期で流れてくるストリームの瞬間をとらえるスナップショット理解のため「非同期処理」を、Dart言語の特徴的で使える機能としてピックアップして解説します。
Dartで定義できるコレクション型(同じ型やクラスであるエレメントをまとめてあつかう集合型)には以下の4種類があります。
Flutterでのデータモデルとアプリ画面間の変換にはListとMapをよく使うので、それらの使い方と変換方法をステップバイステップで説明します。
1. レストランクラスの作成
ID、名前、タイプ、住所、ロゴ画像URL、星の数といった属性をもつクラスを実装し、そのインスタンスを作成しprint表示します。
2. JSONからのレストランクラスの作成
'dart:convert'パッケージに含まれる jsonDecodeメソッドを使うと、一つのドキュメントをあらわす「{ }」から始まるJSON文字列からはマップを作成することができるので、このマップからレストランクラスのインスタンスを作成しprint表示します。
3. マップからレストランクラスを生成するファクトリ
マップからレストランクラスのインスタンスを作成する部分を、レストランクラスにファクトリ関数「fromMap(String id, Map<String, dynamic> data)」を作成して実装します。
4. JSONからのレストランクラスの配列作成
jsonDecodeメソッドを使うと「[ ]」から始まるJSON文字列からはリストを作成することができるので、このリストからレストランクラスの配列を作成します。JSON文字列をよく見ると「[ ]」の中の配列要素はドキュメントをあらわす「{ }」から成り立つのでマップに変換されます。そのマップを3でつくった「fromMap」関数でレストランクラスに変換して、レストランクラスの配列を生成しています。
5. リストからレストランクラスの配列作成
JSON文字列から得られたマップのリストを「.map((val)=>function(val)).toList()」という関数を使って、Restoインスタンスのリストに変換します。このしくみはデータベース上のドキュメントデータをマップとして取得するFirestoreの場合でも利用します。変数名や型が不明なマップからRestoクラスに変換することで、画面表示がプログラミングしやすくなります。
一般的に、プログラム言語における関数処理においては入力と出力から成り立ちます。関数の引数が入力となり、戻り値が出力となるわけです。ここで例えばネット上の画像データを関数の引数にとり、その画像を画面に表示することを考えます。するとこの関数やその戻り値を画面表示するプログラムは、ネットから画像をダウンロードする時間入力値の到着を待つ必要があります。
また複数人によるグループチャットアプリを想像してみてください。だれかがグループあてにメッセージを打ち込むとします。そのメッセージはデータベースに追加されると同時に送信者以外のグループメンバーにブロードキャストされますが、このようなしくみを実装するにはグループチャット用データベースとチャットアプリがリアルタイムでつながっていて、チャットアプリがデータベース上の変化を検知する必要があります。このしくみを支援するプログラム上のしくみがストリームです。今回はデータベースとしてfirestoreを使うので、firestoreとアプリの常時接続や変化の検知、キャッシュや差分更新といったしくみはfirestoreがアプリ用に提供するSDKを使うことができます。Dart言語の方ではチャット内容を表すチャットクラスの配列を用意し、上記のSDKと連携して変化検知のたびにマップからチャットクラスへのデータ変換を行う必要がありますし、こちらがメッセージを送る際はチャットオブジェクトをマップ変換してデータベースに送信する必要があります。
上記に挙げた処理のことを非同期処理と呼びますが、取得する値が一つの値(ネット上の画像ダウンロードのケース)か、コレクション(グループチャットのケース)かによって、Dartでは扱うクラスが異なります。
FutureとStreamの実装例を以下に示します。実際には、FutureもStreamもURLを指定してHTTP経由でデータを取得するクラスやfirestoreのライブラリから取得するので、それらを扱う方法を理解することに集中すれば実装はできるのですが、ここではあえてFutureとStreamのしくみから説明しています。
1. Futureの実装
JSON文字列からレストランオブジェクトを5秒遅れて取得してprint表示するFutureの例です。
2. Streamの実装
JSON文字列から取得したマップのリストから1秒おきにレストランオブジェクトを取得してStreamにsinkしてlistenでprint表示するStreamの例です。
Copyright 2025 RISA Co., LTD.
Dart言語が理解できたらFlutterを使ってさまざまな画面と画面遷移を実装します。ここではFirebaseを使わず、JSONの静的データから「レストランレビューアプリ」の一部の画面と画面遷移を実装します。
Flutterの開発を行うには、画面の部品を構成するWidget(ウィジット)の理解が必要です。「3. 画面設計」でも述べたとおり、画面と画面遷移を構成するにはその裏で状態(ステート)の管理が必要です。例えば、ウィザード遷移を行いアンケートに答える場合には画面間を入力済みのアンケート回答情報をステートに保存し、確認画面表示に利用するとともにデータベースへの送信情報として利用します。FlutterにおけるWidgetにはStatefulWidget(ステートフル・ウィジット)とStatelessWidget(ステートレス・ウィジット)の2種類のWidgetが提供されており、用途によって下記のような使い分けをします。
StatefulWidget: | 一画面の中で状態変数を保持し、変数に変更があったら画面をリロードして変更された変数にあわせて画面表示の変更が必要な画面を実装する際に利用します。「レストランレビューアプリ」では、一画面の中でログインとユーザ登録を切り替える「ログイン画面」とボトムナビゲーションバーを制御する「ホーム画面」、アニメーションで検索用のスライドアップを表示する「レビュー画面」、レビューの編集後に画面リロードが必要な「レビュー詳細画面」、レビューの編集・削除後に画面リロードが必要な「アカウント画面」、レビュー追加後に画面リロードが必要な「レストラン詳細画面」と「レストラン画面」をStatefulWidgetで実装します。 ※(著者メモ)「レビュー詳細画面」「アカウント画面」「レストラン詳細画面」「レストラン画面」はChangeNotifierProviderを使えばStatelessWidgetで実装できるかもしれない。 |
StatelessWidget: | 静的な画面。ChangeNotifierとConsumerを使ってウィジット部品を管理することで、状態変化のたびリロードされる箇所をウィジット部品に限定することができます |
ここではこの両Widgetを理解するために、ブラウザ上でFlutterをプログラミングし実行できるDartpadを使って説明しています。各説明文の下に記載されたリンクをクリックするとDartpadがソースコードと一緒に開きますので、プログラムを実行したい場合は右上のRUNボタンをクリックすると右側の画面にアプリが表示されます。前章と同様にDartpadを本画面上に直接iframeで表示することができるのですが、ブラウザに大量の負荷をかけるため、ワンステップずつDartpad画面を別タブで開いて学習してもらう形式にしています。
StatelessWidgetを使ってシンプルなログイン画面を実装します。
ログインボタンを押すとメールアドレスやパスワードが入力されているか?ルールにのっとって入力されているかをチェックして、条件を満たさない場合エラーメッセージを表示してくれるよう実装します。
FocusNodeクラスを使い、フィールド入力が完了し、エンターを押したら次のフィールドにキー操作が移動し、最後のフィールド入力後エンター押下でログインボタンをクリックしたこととなり、ホーム画面に遷移するよう実装します。
キー入力でフォーカスが移動しホーム画面に遷移するログイン画面
ログイン画面とホーム画面をログイン/ログアウト状態を管理するステートを持つランディング画面でつなげるよう実装します。この実装はのちに利用するProviderの簡易実装です。
ログインボタンと登録ボタンをクリックすることでログイン画面と登録画面を切り替えられるようログイン画面を修正します。一つのWidgetで切り替えを行うにはStatelessWidgetから状態(State)を持つStatefulWidgetに変更が必要なのでLoginクラスにリファクタリングを行います。
ホーム画面にメニューとボトムナビゲーションバーを追加して、3画面切り替えられるように実装します。そのために、StatefulWidgetにリファクタリングして、PageViewを使った実装を行います。
ホーム画面のボトムナビゲーションバーで切り替える画面の一つにJSON文字列から取得したレストランのリストをGridViewで表示する画面を実装します。
RestoPageのGridViewページを追加したホーム画面
Copyright 2025 RISA Co., LTD.
前の2つの章では、Dartpadを使ってブラウザ上でプログラムを試しましたが、ここからはパソコン上のFlutterの開発環境とVSCodeエディタを使った開発を開始してもらいます。開発対象がスマホアプリなので、Android用の開発環境(Android Studio)やiPhone用の開発環境Xcodeが必要と思われがちなのですが、これらは大量のディスクスペースと実行時にハイスペックなCPUと大規模メモリを要求しますので、これを極力回避するためFlutter Webをつかって開発を行うこととします。
Flutter WebというWebアプリを開発するとなるとスマホのネイティブアプリを開発する本書の目的とは違うと思われそうですが、これが真のクロスプラットフォームフレームワークであるFlutterのよいところで、Flutter Webを開発すればそのソースコードがiPhoneアプリとAndroidアプリ用にもほぼそのまま転用できるのです。いくつかスマホ用には対応していないFlutterプラグインがありますが、それらの機能はスマホアプリをコンパイルする際に追加することとして、ここではFlutter Webとしての「レストランレビューアプリ」を開発します。
また、Flutter FlowというWebアプリを使うと、Firebaseとの接続をWeb上の設定で行うことができ、UI開発をGUI形式で行うことが可能です。Flutter Flowのフル機能を使うには月額数千円必要ですが、非常に協力なしくみなので使用を検討するとよいでしょう。サンプルのFlutterMetアプリの構築動画を観るとこのツールの強力さがわかるでしょう。
いままで整理してきたユースケースやデータモデルや画面設計のとおり、顧客がレストランのレビューを書き込むアプリケーションを開発します。できあがったFlutter Webアプリのイメージは下記のとおりです。この画面は裏でFirebaseにつながっており実際のWebアプリケーションとして利用できます。顧客としてユーザ登録を行いレストランを参照しレビューを書き込むことができます。
下記サンプルアプリに Email: ichiro@test.com, Password: password でログインしてみてください。
本書のハンズオンではGithubからソースコードをダウンロードしてきて、Firebaseとの接続設定を行うことでこのアプリケーションをローカル環境で動かすことができるようにします。その後、ソースコードを眺めながら、実装方法について説明をしていきます。
そのために、まずはお手持ちのパソコンにFlutterと開発用エディタであるVSCodeのインストールを行います。
まずはじめに開発に必要なFlutterとエディタであるVS Codeのインストールを行います。
- Flutterのインストール
下記リンクから自らの開発PCのOSを選択してFlutter SDKをインストールします。
https://flutter.dev/docs/get-started/install
本書ではFlutter Webのみを利用しますので、上記リンクに記載のあるAndrlid SetupやiOS Setupの作業は必要ありません。
- VS Codeのインストール
下記リンクに従ってVS Codeをインストールします。
https://flutter.dev/docs/get-started/editor?tab=vscode
- Chromeのインストール
開発したWebアプリをデバッグするためにブラウザが必要ですが、Flutterで推奨されているChromeをインストールします。
https://www.google.com/intl/ja_jp/chrome/
- PowerShellのインストール(Windowsの場合)
Windows環境の場合ターミナルが使いやすくなるように下記リンクからPowerShellをインストールしておくと良いです。
https://github.com/PowerShell/PowerShell
- インストールの確認
上記のインストールが完了しているかを確認するため「flutter doctor」コマンドを実行します。下記の通り、FlutterとVS CodeとChromeにチェック「✔︎」が入っていますが、AndroidとXcodeにはインストールがされていないことを表すバツ「✖︎」が表示されます。
$ flutter doctor Doctor summary (to see all details, run flutter doctor -v): [✓] Flutter (Channel beta, 1.20.0, on Mac OS X 10.15.6 19G2021, locale ja-JP) [✗] Android toolchain - develop for Android devices ✗ Unable to locate Android SDK. Install Android Studio from: https://developer.android.com/studio/index.html On first launch it will assist you in installing the Android SDK components. (or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions). If the Android SDK has been installed to a custom location, set ANDROID_SDK_ROOT to that location. You may also want to add it to your PATH environment variable. [✗] Xcode - develop for iOS and macOS ✗ Xcode installation is incomplete; a full installation is necessary for iOS development. Download at: https://developer.apple.com/xcode/download/ Or install Xcode via the App Store. Once installed, run: sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer sudo xcodebuild -runFirstLaunch ✗ CocoaPods not installed. CocoaPods is used to retrieve the iOS and macOS platform side's plugin code that responds to your plugin usage on the Dart side. Without CocoaPods, plugins will not work on iOS or macOS. For more info, see https://flutter.dev/platform-plugins To install: sudo gem install cocoapods [✓] Chrome - develop for the web [!] Android Studio (not installed) [✓] VS Code (version 1.45.1) [✓] Connected device (2 available) ! Doctor found issues in 3 categories.
Flutterで開発を始めるにあたってflutterコマンドを使ってFlutter Webプロジェクトの初期フォルダを作成します。
- Flutter Webの設定
FlutterによるWebアプリ開発のためには、Flutterコマンド「flutter config --enable-web」を実行してWebアプリ開発を有効化します。
$ flutter --version Flutter 1.21.0-10.0.pre.114 • channel master • https://github.com/flutter/flutter.git Framework • revision b2c0970aa7 (8 hours ago) • 2020-08-16 06:11:02 -0400 Engine • revision b300be3df3 Tools • Dart 2.10.0 (build 2.10.0-34.0.dev) $ flutter config --enable-web Setting "enable-web" value to "true". You may need to restart any open editors for them to read new settings.
- Flutterプロジェクトの作成と実行
Flutterで開発を始めるには"flutter create [プロジェクト名]"というコマンドを使ってFlutterプロジェクトの初期フォルダを作成します。また、コマンドオプション「--org [パッケージ名]」を追加すると、Dartコードから生成されるiOS用SwiftコードやAndroid用Kotlinコードのパッケージ名を指定できます。私はパッケージ名はドメイン名を反対にした形式をとるので、例えば弊社ドメイン名"sonrisa.co.jp"にアプリのグループ名"samples"を追加した"samples.sonrisa.co.jp"を反対にした"jp.co.sonrisa.samples"を指定しましたが、みなさんの環境では自分にあったパッケージ名を決めて実行してください。このパッケージ名はアプリをAppStoreやGoogle Playに登録する際やFirestoreプロジェクトにアクセスできるアプリを登録する際に使われる重要なものなので、あらかじめルールを決めて指定するように心がけましょう。また、ここでのプロジェクト名は、レストランレビューを登録するアプリであるため「RestoReview」にしてFlutter Webプロジェクトを作成します。
$ flutter create --org jp.co.sonrisa.samples RestoReview Creating project RestoReview... RestoReview/ios/Runner.xcworkspace/contents.xcworkspacedata (created) ... Running "flutter pub get" in RestoReview... 2.5s Wrote 76 files. All done! [✓] Flutter: is fully installed. (Channel master, 1.21.0-10.0.pre.114, on Mac OS X 10.15.6 19G2021, locale ja-JP) [✗] Android toolchain - develop for Android devices: is not installed. [✗] Xcode - develop for iOS and macOS: is not installed. [✓] Chrome - develop for the web: is fully installed. [!] Android Studio: is not available. (not installed) [✓] VS Code: is fully installed. (version 1.45.1) [✓] Connected device: is fully installed. (2 available) Run "flutter doctor" for information about installing additional components. In order to run your application, type: $ cd RestoReview $ flutter run Your application code is in RestoReview/lib/main.dart.
プロジェクトを作成するとプロジェクト名のフォルダが作成されます。その中身は下記のとおり、プロジェクトの設定を行う"pubspec.yaml"ファイル、Dart言語で書かれたソースコードを置く"lib"フォルダ、プラットフォームごとに自動生成されたソースコードを置く"ios"、"android"、"web"フォルダなどから構成されます。
RestoReview $ tree . . ├── pubspec.yaml ├── lib │ └── main.dart ├── ios ... ├── android ... └── web ├── favicon.png ├── icons │ ├── Icon-192.png │ └── Icon-512.png ├── index.html └── manifest.json 50 directories, 80 files
また、初期状態としてカウンターアプリが生成されますので、それを実行します。
$ cd RestoReview $ flutter run -d chrome
するとChromeブラウザが開き、カウンターアプリが表示されます。
本Flutterプロジェクトは、インストール確認テスト用に作成したものなのでまるまる削除してください。
Copyright 2025 RISA Co., LTD.
Flutter開発の初期設定が完了したのでインフラ部分を担うFirebaseの設定を行います。また途中でGithubリポジトリから「RestoReview」プロジェクトをダウンロードして、Firebaseから利用できるよう設定を行います。
Firebase Consoleにログインして「プロジェクトを追加」をクリックし、名前を「RestoReview」と命名し、「続行」ボタンをクリック、Google Analyticsの設定後、「プロジェクトを作成」ボタンをクリックしてFirebaseプロジェクトを作成します。
Firebaseには様々な認証をサポートする機能としてFirebase Authenticationがあります。画面左メニューから「Authentication」を選択し、「Sign-in method」タブを選択します。
「メール/パスワード」を有効化するため、「Authentication」画面のログインプロバイダのリストの最上部「メール/パスワード」行右端の鉛筆アイコンを選択し表示される下記ダイアログで「有効にする」を選択し、保存ボタンをクリックします。
さらに「Authentication」画面の「Users」タブを選んで、「ユーザ追加」から下記の3つのメールアドレスを追加しておいてください。パスワードは任意です。これらのユーザは「RestoReview」アプリから利用します。
アプリケーションが利用するデータベースとしてCloud Firestoreを有効化します。
以上によりRestoReviewプロジェクトでCloud Firestoreが使えるようになります。
下記コマンドを実行して、GithubからFlutterプロジェクト「RestoReview」をダウンロードします。
$ git clone https://github.com/david3080/RestoReview.git ... $ cd RestoReview/
Firebaseのコマンドラインインタフェース(CLI)を使うと、開発したWebアプリや設定ファイルをFirebaseに直接デプロイすることができます。本作業は前回ダウンロードした「RestoReview」フォルダ下で実行します。
$ npm -g install firebase-tools
$ firebase --version
$ $ firebase login i Firebase optionally collects CLI usage and error reporting information to help improve our products. Data is collected in accordance with Google's privacy policy (https://policies.google.com/privacy) and is not used to identify you. ? Allow Firebase to collect CLI usage and error reporting information? Yes
ChromeブラウザがオープンしてFirebaseにログインするアカウントの選択を促してくるので、該当アカウントを選択してログインします。
ログインが成功するとFirebase CLIに許可を求められるので「許可」ボタンをクリックして許可すると...
ログインが成功します。
$ firebase projects:list
$ firebase use restoreview-xxxxx
$ firebase init
######## #### ######## ######## ######## ### ###### ######## ## ## ## ## ## ## ## ## ## ## ## ###### ## ######## ###### ######## ######### ###### ###### ## ## ## ## ## ## ## ## ## ## ## ## #### ## ## ######## ######## ## ## ###### ######## You're about to initialize a Firebase project in this directory: /.../RestoReview ? Which Firebase CLI features do you want to set up for this folder? Press Space to select features, then Enter to confirm your choices. ? Which Firebase CLI features do you want to set up for this folder? Press Space to select features, then Enter to confirm your choices. ◯ Database: Deploy Firebase Realtime Database Rules ◉ Firestore: Deploy rules and create indexes for Firestore ◉ Functions: Configure and deploy Cloud Functions ◉ Hosting: Configure and deploy Firebase Hosting sites ❯◉ Storage: Deploy Cloud Storage security rules ◯ Emulators: Set up local emulators for Firebase features
=== Firestore Setup Firestore Security Rules allow you to define how and when to allow requests. You can keep these rules in your project directory and publish them with firebase deploy. ? What file should be used for Firestore Rules? (firestore.rules)
Firestore indexes allow you to perform complex queries while maintaining performance that scales with the size of the result set. You can keep index definitions in your project directory and publish them with firebase deploy. ? What file should be used for Firestore indexes? (firestore.indexes.json)
=== Functions Setup A functions directory will be created in your project with a Node.js package pre-configured. Functions can be deployed with firebase deploy. ? What language would you like to use to write Cloud Functions? TypeScript ? Do you want to use TSLint to catch probable bugs and enforce style? Yes ✔ Wrote functions/package.json ✔ Wrote functions/tslint.json ✔ Wrote functions/tsconfig.json ✔ Wrote functions/src/index.ts ✔ Wrote functions/.gitignore ? Do you want to install dependencies with npm now? (Y/n)
=== Hosting Setup Your public directory is the folder (relative to your project directory) that will contain Hosting assets to be uploaded with firebase deploy. If you have a build process for your assets, use your build's output directory. ? What do you want to use as your public directory? build/web ? Configure as a single-page app (rewrite all urls to /index.html)? No ✔ Wrote build/web/404.html ✔ Wrote build/web/index.html
=== Storage Setup Firebase Storage Security Rules allow you to define how and when to allow uploads and downloads. You can keep these rules in your project directory and publish them with firebase deploy. ? What file should be used for Storage Rules? storage.rules i Writing configuration info to firebase.json... i Writing project information to .firebaserc... ✔ Firebase initialization complete!
画面灰色部分を先ほどダウンロードした「RestoReview」フォルダ配下の「web/index.html」ファイル内の下記箇所に上書き保存します。
// ここを上書きする const firebaseConfig = { apiKey: "...", authDomain: "...", databaseURL: "...", projectId: "...", storageBucket: "...", messagingSenderId: "...", appId: "...", measurementId: "..." }; // ここまで
$ pwd .../RestReview $ flutter build web
$ firebase deploy --only hosting === Deploying to 'restoreview-824b4'... i deploying hosting i hosting[restoreview-824b4]: beginning deploy... i hosting[restoreview-824b4]: found 15 files in build/web ✔ hosting[restoreview-824b4]: file upload complete i hosting[restoreview-824b4]: finalizing version... ✔ hosting[restoreview-824b4]: version finalized i hosting[restoreview-824b4]: releasing new version... ✔ hosting[restoreview-824b4]: release complete ✔ Deploy complete! Project Console: https://console.firebase.google.com/project/restoreview-824b4/overview Hosting URL: https://restoreview-824b4.web.app
Copyright 2025 RISA Co., LTD.
ここでは
「レストランレビューアプリ」の画面設計で説明した「①ログイン、メニュー選択、ログアウト」の各画面は図のようなクラスで実装されています。
1. ログイン画面(LoginPage)の実装
(TODO)
2. LandigPageの実装
ログイン状態を随時チェックしてログイン画面(LoginPage)とホーム画面(HomePage)を切り替えるためにLandingPageが配置されています。
(TODO)
3. ホーム画面(HomePage)の実装
(TODO)
「レストランレビューアプリ」の画面設計で説明した「②レストランリストとレストラン詳細、レビュー表示とレビュー追加」の各画面は図のようなクラスで実装されています。
1. レストラン画面(RestoPage)の実装
(TODO)
2. レストラン詳細画面(RestoDetail)の実装
(TODO)
3. レビュー詳細(ユーザ画面付)画面(UserReviewDetail)の実装
(TODO)
4. レビュー追加画面(ReviewEdit)の実装
(TODO)
「レストランレビューアプリ」の画面設計で説明した「③全レビューリストとレビュー表示」の各画面は図のようなクラスで実装されています。
1. レビュー画面(ReviewPage)の実装
(TODO)
2. レビュー詳細(ユーザ画面付)画面(UserReviewDetail)の実装
(TODO)
「レストランレビューアプリ」の画面設計で説明した「④アカウント表示と自分が投稿したレビューの管理」の各画面は図のようなクラスで実装されています。
1. アカウント画面(AccountPage)の実装
(TODO)
2. レビュー詳細(ReviewDetail)の実装
(TODO)
3. レビュー編集(ReviewEdit)の実装
(TODO)
Copyright 2025 RISA Co., LTD.
(TODO) StatefulWidgetとStatelessWidgetの違い、Stateの意味、Providerパッケージ、RiverPodパッケージ、GetXパッケージ、RxDartパッケージなどを説明します。
#1 - Why BLoC? | BLoC - from Zero to Hero
Copyright 2025 RISA Co., LTD.
(TODO)
Copyright 2025 RISA Co., LTD.
(TODO)
https://codelabs.developers.google.com/codelabs/flutter-app-testing/#0
https://qiita.com/yujikawa/items/fe509b160df5ab9eb74e
Copyright 2025 RISA Co., LTD.
(TODO) Flutter WebプロジェクトにAndroidとiOS用フォルダを追加する方法(flutter create . --org [パッケージ名])。XcodeインストールとAndroid SDK(コマンドのみhttps://qiita.com/undrthemt/items/1861d5fe39be46a2b776)をインストールしてビルドする方法。Firebaseにアプリを追加して必要ファイルをダウンロードして配置する方法。)
Copyright 2025 RISA Co., LTD.
(TODO) Firebase App Distributionの方法を解説
https://firebase.google.com/docs/app-distribution/ios/distribute-console?hl=ja
Copyright 2025 RISA Co., LTD.
(TODO) 本書での構成はフロントのネイティブアプリ開発はFlutterにまかせ、バックエンドもFirebaseにまかせるので、APIやWebアプリの開発は発生せず、それらの脆弱性は考える必要がない。そのため、Flutterで構築するネイティブアプリの脆弱性回避とFirebaseの主要機能であるFirestoreとFirestorageとCloud Functionsで妥当なセキュリティルールの設定をすることに注力するだけでよい。あとは脆弱性診断など第三者によるチェックの仕方を考えることくらい。
APIキーについて、Firebase HostingでもAPIキーファイルはJSとして提供されて誰でもダウンロードできるようになっているので、誰にもアクセスできないようにすべきものではない。大事なのはセキュリティルール。
参考)Flutterアプリ開発七つの大罪:https://qiita.com/__naoya__/items/98ac66157a1578be2798
参考)Flutter Security:https://flutter.dev/security
参考)How to make a flutter app with high security? :https://medium.com/flutter-community/how-to-make-a-flutter-app-with-high-security-880ef0aa54da
参考)Mobile App Security:https://www.linkedin.com/pulse/mobile-app-security-native-vs-flutter-rick-wu
参考)Storing your secret keys in Flutter:
https://medium.com/@sokrato/storing-your-secret-keys-in-flutter-c0b9af1c0f69
参考)Do you need to hide your Firebase API keys for Ionic apps?
https://javebratt.com/hide-firebase-api/
参考)多くのモバイルアプリに「バックドアシークレット」、オハイオ州立大などが発表
https://www.atmarkit.co.jp/ait/articles/2004/19/news014.html
Copyright 2025 RISA Co., LTD.
(TODO)
Firebase参考:https://www.youtube.com/watch?v=iWEgpdVSZyg
せっかくFirebaseに一本化したのでサービスの稼働状況をスマホアプリから見れるようにするとよいかも https://status.firebase.google.com/
Copyright 2025 RISA Co., LTD.
(TODO)
Copyright 2025 RISA Co., LTD.