Firebase Remote Configの設定値にHTML, JSON, JavaScriptを設定してパース・実行してみた

# 利用環境
macOS 10.12.6
Xcode 9.2

# Firebase Remote Configの設定値の制約
https://firebase.google.com/docs/remote-config/parameters?hl=ja
公式のドキュメントの「パラメータと条件の制限」によると、

> Firebase プロジェクト内には、最大 2,000 個のパラメータ、最大 500 個の条件を設定できます。パラメータキーの長さは最大 256 文字で、アンダースコアまたはアルファベット （A～Z、a～z）で始める必要があります。数字を使用することもできます。プロジェクト内のパラメータ値文字列の合計長は、800,000 文字以内にする必要があります。

「パラメータ値文字列の合計が800,000文字以内」ってなかなか上限には達しないけど、もし、この上限まで達するとすれば、どんな文字列があるだろうか・・・・と考えて、検証するのが下記の３つ
・HTML
・JSON
・JavaScript

## Firebase Console
Remote Configのコンソール上で、HTML, JSON, JavaScriptを設定する。

![firebase_remote_config.png](https://qiita-image-store.s3.amazonaws.com/0/212023/7d9ffe91-adf4-bbbb-adcb-827977849203.png)

今回、下記の３つのキーに設定された値を利用する。
・test_html
・test_json
・test_js

## WebViewの準備
HTML、JavaScriptの動作検証用に、WKWebViewを配置したViewControllerを用意する。
javascriptがalertが呼ばれた時に何か処理を実行するために、WKUIDelegateも設定

```swift:ViewController.swift

import Foundation
import WebKit

class WebViewController: BaseViewController, WKUIDelegate {
    
    var webView: WKWebView?
    
    override func viewDidLoad() {
        super.viewDidLoad()
                
        // webviewの初期化処理
        self.webView = WKWebView(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: self.view.frame.size.height))
        self.webView?.uiDelegate = self
        
        self.view.addSubview(webView!)
    }
    
    /// WKUIDelegate

    func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
        print("javascriptでalertが呼ばれた")
    }
}

```

## HTML
HTMLの文字列をパースして、webViewに表示する。

```swift:ViewController.swift

override func viewDidLoad(){

    // 中略
    
    // Firebase Remote Configから"test_html"に設定されたHTMLの文字列を取得する。
    let remoteConfig = RemoteConfig.remoteConfig()
    let remoteConfigSettings = RemoteConfigSettings(developerModeEnabled: true)
        remoteConfig.configSettings = remoteConfigSettings!
        remoteConfig.setDefaults(fromPlist: "remoteConfigDefaults")

    let htmlString = remoteConfig["test_html"].stringValue
    self.webView?.loadHTMLString(htmlString!, baseURL: nil)   
}

```

## JSON
JSONをパースして、コンソールに表示してみる。

```swift:ViewController.swift
override func viewDidLoad(){

    // 中略
    
    // Firebase Remote Configから"test_json"に設定されたJSONの文字列を取得する。
    var escapedJsonString = remoteConfig["test_json"].stringValue
    let jsonData = escapedJsonString?.data(using: .utf8)
    var dict: [String : Any]?
    do{
        dict = try JSONSerialization.jsonObject(with: jsonData!, options: []) as? [String : Any]
        //利用したいデータのkeyを指定してデータ取り出し
    } catch {
        print(error.localizedDescription)
    }
    print(dict)
}

```
RemoteConfigからjsonを取り出した直後は、ダブルクォートがエスケープされた状態になっている。
JSONパースして、アプリに必要な値は、取り出して画面に反映するのが良さそう。


## JavaScript
JavaScript文字列を取得して、webViewで表示中のwebサイトに、javascriptを実行してみる。

```swift:ViewController.swift
override func viewDidLoad(){

    // 中略


    // Firebase Remote Configから"test_js"に設定されたJavaScriptの文字列を取得し、実行する
    let jsString = remoteConfig["test_js"].stringValue
    self.webView?.evaluateJavaScript(jsString!, completionHandler: { (obj, error) in })
}
```

自前の環境の設定値とはいえ、アプリ外から取得したJavaScriptが設定できて、
それを実行できるというのは少々怖い・・・

# まとめ
HTML, JSON, JavaScriptをFirebase Remote Configから取得して、それをアプリ側に反映させるのは可能なようだった。
文字列の制限があるから、実際に設定するデータはMinifyしておく必要はありそう。
そうなると、専用のフォームを作ってあげる必要がありそうですね。
Remote ConfigはREST APIが利用可能なため、これを利用した管理ツールを作るのが良さそう。
https://firebase.google.com/docs/remote-config/use-config-rest?hl=ja