Flutter環境でFirebase Remote Configを使ってみる

# はじめに
株式会社THIRD IT開発部でモバイル開発チームでアプリ（Android及びiOS）の開発を行なっているエンジニアです。
弊社では不動産の点検や作業報告などをスマートフォンで行うためのアプリとして，管理ロイド等のアプリを開発及びリリースしています。

新しいプロダクトのアプリ開発はFlutterにて開発をしていこうかと検討しています。
その一環でFirebase Remote Configの導入について記載していこうと思います。

# Firebase Remote Configとは
[公式サイト](https://firebase.google.com/docs/remote-config?hl=ja)では、次のように記載されています。


> アプリのアップデートを公開しなくても、アプリの動作と外観を変更できます。コストはかからず、1 日あたりのアクティブ ユーザー数の制限もありません。
>
> Firebase Remote Config は、ユーザーにアプリのアップデートをダウンロードしてもらわなくても、アプリの動作や外観を変更できるクラウド サービスです。Remote Config を使用して、アプリの動作や外観を制御するためのアプリ内デフォルト値を作成できます。その後、Firebase コンソールか Remote Config バックエンド API を使用して、すべてのアプリユーザーまたはユーザーベースの特定セグメントに対して、アプリ内デフォルト値をオーバーライドできます。アップデートを適用するタイミングはアプリ側で制御できます。アプリはアップデートの有無を頻繁にチェックし、パフォーマンスにほとんど影響をおよぼすことなくアップデートを適用できます。

要約するとアプリ側からFirebase上のRemote Configの値を見てアプリの動きを切り替えるように使います。

> **注**：アプリ側で対応していない値をFirebase Remote Configで設定しても正しく動きません。

## 使用用途

* 強制バージョンアップ
* メンテナンスモード
* Feature Flag

などで使われる事が多いのではないかと思います。

# Flutterへの導入方法
## 1. Flutterプロジェクトの作成（なければ）
### 1.1.　**New Flutter Project**よりFlutterのプロジェクトを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170755/873c95b1-3a96-d15f-19c1-cb5ea064f78d.png)

### 1.2.　プロジェクト名を設定
### 1.3.　アプリを実行できる事を確認

## 2.　Firebase プロジェクト作成（なければ）
### 2.1. Firebaseのプロジェクトの作成から**Remote config sample**プロジェクトを作成する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170755/bd7e4aa4-bbdf-3a7b-9801-688f44f95fb9.png)

### 2.2. アプリの登録
iOSのアイコンまたはAndroidのアイコンから登録画面へ遷移できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170755/d63879b5-5209-2712-bd5c-fd7da5b5c3d3.png)

### 2.3. Androidアプリの登録
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170755/edab5394-4607-0177-ffa4-6d5b5da12a6b.png)

### 2.4. google-services.jsonをダウンロード（アプリ側で使用）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170755/d90e7290-e984-cfc7-726f-f68c11185c22.png)

### 2.5. iOSアプリの登録
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170755/c0a6fd01-2de3-b915-5681-14c321f463ff.png)

### 2.6. GoogleService-Info.plistをダウンロード（アプリ側で使用）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170755/8de742d7-737c-1d14-d110-6c7e22d72518.png)


## ３.　Firebase のRemote configを設定
### 3.1.　トップページの`すべての 構築 の機能を表示`を選択し
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170755/3b95b867-ef10-78f6-60d9-da0ad69c37b3.png)

### 3.2.　エンゲージメント欄の`Remote Config`を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170755/0e16489a-af77-8540-2c8c-93838f636363.png)

### 3.3.　`構成を作成`を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170755/5c26eea1-03ee-779d-ef38-add7f16d1bb3.png)

### 3.4.　パラメータを設定し保存する
例としてbool値の`maintenance_mode`で設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170755/4d8216cd-8503-82d4-b40b-0572ecc9f227.png)

### 3.5.　変更を公開する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170755/f2cfc751-74d9-5438-8ba9-d2865b6d5ba9.png)


これでFirebaseのRemote configを設定が完了です。アプリでどのようにこの値を取得するか次章で記載していきます。

## 4. アプリ側でRemote configを読むための実装
### 4.1 Firebase Remote configのインストール
プロジェクトのルートディレクトリで下記コマンドを実行

```sh
$ flutter pub add firebase_remote_config
```

### 4.2. アプリが起動できることを確認

### 4.3. Android側の設定
ダウンロードしておいた`google-services.json`をプロジェクトフォルダーの`android/app/google-services.json`へ移動します。

また、下記に従いAndroid アプリへの Firebase の追加の設定を行う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170755/1a95a57e-1df3-2645-1676-55059a5122f0.png)

### 4.4. iOS側の設定
ダウンロードしておいた`GoogleService-Info.plist`をプロジェクトフォルダーの`ios/Runner/GoogleService-Info.plist`へ移動します。

### 4.5. Firebase Remote configの値を取得する
[公式サイト](https://firebase.google.com/docs/remote-config/get-started?platform=flutter&hl=ja#2_get_the_remote_config_singleton_object)を参照してください。

まず、Remote Config オブジェクトのインスタンスを取得

```kotlin
    final FirebaseRemoteConfig remoteConfig = FirebaseRemoteConfig.instance;
    await remoteConfig.setConfigSettings(RemoteConfigSettings(
      fetchTimeout: const Duration(seconds: 10),
      minimumFetchInterval: Duration.zero,
    ));
```

次に、アプリ上で使用する`maintenance_mode`のデフォルトパラメータ値を設定

```kotlin
    await remoteConfig.setDefaults(<String, dynamic>{
      "maintenance_mode": false,
    });
```

Firebase Remote configの値（`maintenance_mode`）を取得

```kotlin
      await remoteConfig.fetchAndActivate();
      var isMaintenance = remoteConfig.getBool("maintenance_mode");
```

## 5. 最後に
[サンプルコード](https://github.com/sacred-sanctuary/remote_config_sample)に上記の大まかな実装を含めたサンプルコードがあります。