【0からのflutter/part1】Cloud Firestoreの設定をしてFlutter公式のサンプルアプリを動かす。

# はじめに

Flutter初心者が[公式のサンプル](https://flutter.github.io/samples/flutter_maps_firestore.html)を見ながら動きを勉強していく記事です。
細かいコードの解説をするのではなく、詰まった点のメモや解決方法の記事のリンクなどをまとめて載せていきます。
この記事を読むと、以下のアプリが完成します。

- flutterアプリケーションをfirebaseに接続
- Cloud Firestoreからデータを取得
- データをgoogle map上のmarkerに変換
- marker情報を表示するカルーセルを設置
- カルーセルタップで該当のピンの位置を画面の中心に移動


<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270898/71c93798-dfe5-d9d5-9d9e-cbabbf0ddcf8.png">

完成形のコード。

https://github.com/flutter/samples/tree/master/flutter_maps_firestore


# mapの実装
## 開発環境の構築

開発環境の設定は、以下の記事ですでに行なっている。

https://qiita.com/ninoko1995/items/d2976d9ca6951ed50520

## プロジェクトの作成

AndroidStudioを開き、新規Flutterプロジェクトを作成する。
作りたてのアプリを起動すると、以下のようなものができている。
すでに動くアプリが作れてるのすごいな。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270898/cf3b7c80-c742-f746-2300-89dc03252d85.png">

## google map apiの利用

以下の2つの記事を参考に、google map apiの登録からアプリへのmap表示までを行う。
基本は一つ目の記事でいいんだけど、日本語ではないから二つ目の記事と合わせて読むとより理解が深まるかも。

https://pub.dev/packages/google_maps_flutter#sample-usage

https://www.nskint.co.jp/2021/06/30/google_flutter_column_2/



上記の記事に従って進めたところ、

```
Cannot resolve symbol 'Properties'
Cannot resolve symbol 'GradleException'
```
といったエラーが発生した。このエラーを調べると、以下の記事の対応を行うと解消されることがわかった。

https://moimoiblog.com/programing/flutter-cannot-resolve-symbol-properties/

こうして、Flutterの公式のpackageのサンプルコードを実装した。
とりあえずgoogle mapをアプリに組み込むことに成功！

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270898/a5f44eb9-57be-47e0-fe5f-883022c24394.png">

## ファイルの分割

一つのファイルに全部書くと管理が大変なので、以下のようにファイルを分けた。

- lib
  - widgets : main以外のwidgetを記述したファイルを入れておくもの
     - counter_demo.dart : 既存のデモアプリのwidgetを記述
     - map_demo.dart : 新たに作成したmapのデモアプリのwidgetを記述
  - main.dart 

別ファイルのwidgetを読み込む方法は、以下の記事を参考にした。

https://qiita.com/k_mawa82/items/9496e1e241ca6aa867b0

## mapの見た目を変える

上記画像の問題点が2点。

- google mapの見た目が衛生写真であること。
- ホームボタンと現在地ボタンが重なってしまっていること。

両方とも、以下の記事の動画の中で解説されていたのでそれを参考にコードを修正する。

https://www.nskint.co.jp/2021/06/30/google_flutter_column_2/

動画を見直すのはだるいので、変更部分のコードのみ記録しておく。

```dart:map_demo.dart
@override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: GoogleMap(
        mapType: MapType.normal, //←変更
        initialCameraPosition: _kGooglePlex,
        onMapCreated: (GoogleMapController controller) {
          _controller.complete(controller);
        },
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,　//← 追記
      floatingActionButton: FloatingActionButton.extended(
        onPressed: _goToTheLake,
        label: Text('To the lake!'),
        icon: Icon(Icons.directions_boat),
      ),
    );
```

これでなんかそれっぽくなってきた！！

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270898/45ffb91e-1f4d-d5ef-a65d-c11c017e0abf.png">



# サンプルアプリの実装
google_mapを表示する際に必要なコードがわかった。
次は実際にサンプルのアプリのコードを少しずつ移植していき、自分のアプリに組み込んで行ってみる。

https://github.com/flutter/samples/tree/master/flutter_maps_firestore

## Cloud Firestoreの設定
以下の記事を参考に、cloud fire storeを使えるようにする。

- 新たなFirebaseプロジェクトの作成
- 作成したプロジェクト内でCloud Firestoreの利用を開始

https://firebase.google.com/docs/firestore/quickstart

## Cloud Firestoreへデータ登録
利用開始したCloud Firestoreに対して、以下の形式のデータを登録する。
Cloud Firestoreを利用したことがないのであっているかわからないが、とりあえずこれで進めてみる。

https://github.com/flutter/samples/tree/master/flutter_maps_firestore#cloud-firestore

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270898/5117208f-6fcb-e205-4cb0-1d2a0c9d7b12.jpeg">


## Cloud Firestoreパッケージの導入
flutterでCloud Firestoreを利用できるように、`pubspec.yaml`ファイルに`cloud_firestore`の追加を行う。

https://firebase.flutter.dev/docs/firestore/overview/

ちなみに、null-safetyのやつが混じっているとかなんとか色々エラーが出たので、以下の対応を行なった。

- `cloud_firestore`を2021年9月時点での最新版である`2.5.2`をインストールするように修正
- `/ios/Podfile`にて、使用するiOSのバージョンを11以上とするように修正

```
# Uncomment this line to define a global platform for your project
platform :ios, '11.0'
```

- `pod repo update`の実行


## コードの記述
実際にflutterでCloud Firestoreにアクセスし、取得した位置情報をgoogle map上に表示するアプリを作成する。
`/lib/widgets/`配下に、`firestore_demo.dart`を作成して、そこに必要なコードを追加していく。
今回はサンプルのほぼコピペでいく。

https://github.com/flutter/samples/blob/master/flutter_maps_firestore/lib/main.dart

Cloud Firestoreのflutter用のパッケージの利用説明なんかは以下のページにあるから、これを読むと何してるか理解しやすいかも。

https://firebase.flutter.dev/docs/firestore/usage/

## targetをiOS9以降に設定
ターゲットがサポートされていない旨のエラーが出た。

```
warning: The iOS Simulator deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.5.99. (in target 'gRPC-Core' from project 'Pods')
```

解決方法

https://qiita.com/temoki/items/46ad22940e819a132435

## FlutterアプリにFirebaseを組み込む

GoogleSearvice-Info.plistを設置しろというエラーが出た。
確かに、firebaseをflutterから使うための設定を何もしていなかった。

```
[VERBOSE-2:ui_dart_state.cc(199)] Unhandled Exception: [core/not-initialized] Firebase has not been correctly initialized. Have you added the "GoogleService-Info.plist" file to the project? 
```

以下の記事に従って、設定を行なっていくことで解消された。

https://dolphinetech.com/flutter/flutter-firebase-import/

ちなみにFirebase公式が出している記事は以下。

https://firebase.google.com/docs/flutter/setup?hl=ja&platform=ios

# 完成品の挙動

<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270898/de13aae0-5b75-cac3-cc93-54fdd710abed.gif">
(qiitaに載せるためにgifの枚数をめっちゃ少なくしたので、すごい見にくくなってしまっている...)


今後の展望

- 自分のサーバから取得したデータで同じ処理をできるようにする。
- ショップリストページを作成し、ボタンタップで二つのページを行き来できるようにする。


# 参考

公式のgithubのサンプルアプリ

https://flutter.github.io/samples/flutter_maps_firestore.html