Help us understand the problem. What is going on with this article?

[サーバーレス]UnityとFirebaseでアプリのアップデートをせずに、動作と外観の変更を行う

この記事は、鹿児島大学生 Advent Calendar 2019の21日目の記事です。

概要

以前、クライアントからの要件でサーバーを準備せずにアプリ内の表示を変更したいという要望があったので、その時に行なった対応と、UnityとFirebaseの連携を簡単に解説します。

今回はできるだけシンプルな状態で実装まで行おうと思います。
上手く活用すると、アプリの背景画像の変更を行なったり、広告表示の頻度もデータをみながら即時反映することができます。
またFirebaseとの連携でA/Bテストへの応用も簡単に行うことができます。

環境

  • iMac Catalina 10.15.1
  • Unity 2019.3.0f3
  • Firebase for Unity 6.8.1

Catalinaだと訳あってUnity2019.2系が上手く動いてくれないのでまだ正式リリースされていない2019.3系で行います。。。
UIが変わったのは個人的には好きです。

セットアップ

Firebaseは、Googleのプラットフォームでいくつものサービスがありますが
今回はRemote Configを使用していきます。
スクリーンショット 2019-12-18 21.17.27.png

Unityのプロジェクト構築

まずはサンプルプロジェクトを作成していきます。
中身はなんでもいいのですが、今回は2DプロジェクトでFirebaseからデータを取得するボタンと取得した文言を表示するテキストを準備します。
こちらのやり方は、Unity ボタンとかUnity Textなどで調べるとすぐにわかるので今回は割愛します。
スクリーンショット 2019-12-18 21.21.54.png

Firebaseプロジェクトを追加

Firebaseを使用するため、Firebaseコンソールからプロジェクトを追加していきます。
スクリーンショット 2019-12-18 21.26.40.png

手順2でのアナリティクスは有効にすることで他のFirebaseのサービスと連携することができるのですが、
今回はできるだけシンプルに考えられるようにしたいので、Offにします。
実際は有効にして使うことがほとんどです。
スクリーンショット 2019-12-18 21.28.51.png

Unityアイコンから構成ファイルの作成を行なっていきます。
スクリーンショット_2019-12-18_21_30_25.png

Register as iOS appとRegister as Android appにチェックを入れてバンドルIDとパッケージ名を登録していきます。
ここは後から変更ができないので、先にストアの作成からしてバンドルIDとパッケージ名を確定しておいた方がいいかもしれません。
スクリーンショット 2019-12-18 21.44.09.png

構成ファイルがダウンロードできるので、指示通りダウンロードしてUnityのAssets直下にDDで追加します。
構成ファイルはAssets直下であればSDKがよしなに読み取ってくれるので任意のフォルダに整理しても大丈夫です。
スクリーンショット 2019-12-18 21.52.12.png

SDKをダウンロードしインポートします。
スクリーンショット 2019-12-18 21.55.11.png

zipを解凍したらdotnet3dotnet4のフォルダが作成されます。
Unity 5.0以前では、.NET 3.x フレームワークを使用しているため、dotnet3フォルダのpackageを使用します。
Unity 2017.x以降では.NET 4.x フレームワークを使用できるため.NET 4.xを使用する場合はdotnet4フォルダのpackageを使用します。
FirebaseRemoteConfig.unitypackageをダブルクリックで開いているUnityプロジェクトにインポートできます。
スクリーンショット 2019-12-18 22.00.07.png
スクリーンショット 2019-12-18 22.08.05.png

インポートまで完了したらセットアップは完了です。

実装

Android 向け Firebase Unity SDK には Google Play 開発者サービスが必要であり、SDK を使用する前に最新版にしておく必要があります。
アプリケーションの先頭に次のコードを追加します。
SDK で他のメソッドを呼び出す前に Google Play 開発者サービスを確認し、必要であれば、Firebase Unity SDK で必要とされるバージョンに更新するようにします。

初期化

    void Start()
    {
        Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task =>
        {
            var dependencyStatus = task.Result;
            if (dependencyStatus == Firebase.DependencyStatus.Available) {
                // 使用する準備が整った時に通る
            } else {
                Debug.LogError(String.Format("すべてのFirebase依存関係を解決できませんでした: {0}", dependencyStatus));
            }
        });
    }

デフォルトパラメータ値の設定

Remote Config オブジェクトにデフォルトのパラメータ値を設定しておくと、Firebaseから値を取得できない場合にデフォルト値を使用するようにできます。
これにより、オフラインなどの状況でもアプリがクラッシュしないようにできます。

      // リモート設定を初期化し、デフォルト値を設定します。
    void InitializeRemoteConfig() {
        Dictionary<string, object> defaults = new Dictionary<string, object>();
        defaults.Add("remote_string_value", "ローカルの文字です。");
        FirebaseRemoteConfig.SetDefaults(defaults);
    }

パラメータ値の取得

Firebaseからデータをフェッチすることでデータを取得できます。

    //フェッチリクエストを開始します。
    public Task FetchDataAsync() {
      Debug.Log("データを取得しています...");
      System.Threading.Tasks.Task fetchTask = Firebase.RemoteConfig.FirebaseRemoteConfig.FetchAsync(
          TimeSpan.Zero);
      return fetchTask.ContinueWithOnMainThread(FetchComplete);
    }

    void FetchComplete(Task fetchTask) {
      if (fetchTask.IsCanceled) {
          Debug.Log("フェッチはキャンセルされました。");
      } else if (fetchTask.IsFaulted) {
          Debug.Log("フェッチでエラーが発生しました。");
      } else if (fetchTask.IsCompleted) {
          Debug.Log("フェッチが正常に完了しました!");
      }

      var info = Firebase.RemoteConfig.FirebaseRemoteConfig.Info;
      switch (info.LastFetchStatus) {
        case Firebase.RemoteConfig.LastFetchStatus.Success:
          Firebase.RemoteConfig.FirebaseRemoteConfig.ActivateFetched();
          Debug.Log(String.Format("リモートデータがロードされ、準備完了 (最終取得時間{0}",
                                 info.FetchTime));
          break;
        case Firebase.RemoteConfig.LastFetchStatus.Failure:
          switch (info.LastFetchFailureReason) {
            case Firebase.RemoteConfig.FetchFailureReason.Error:
              // 不明な理由でフェッチに失敗しました
              break;
            case Firebase.RemoteConfig.FetchFailureReason.Throttled:
              Debug.Log( info.ThrottledEndTime + "まで取得を抑制");
              break;
          }
          break;
        case Firebase.RemoteConfig.LastFetchStatus.Pending:
          Debug.Log("最新のフェッチ呼び出しはまだ保留中です。");
          break;
      }
    }

パラメータ値を使用するにはGetBalue()関数を使用します。

var value = Firebase.RemoteConfig.FirebaseRemoteConfig.GetValue("remote_string_value").StringValue;

これらを使用して、ボタンを押したらフェッチを行います。
先ほど作成したテキストに状態を表示できるようにしていきます。
Debug.LogをすべてDebugLogに置き換えることで表示を更新できるようにします。

 //デバッグログテキストフィールドとコンソールにテキストを出力します。
    public void DebugLog(string s)
    {
        uiText.text = s;
    }

あとはこれらをUnityに設定していきます。

動作確認

33527-pabho.gif

このままだと、まだデフォルトしか表示されていないので次にFirebase側で更新したいパラメータを設定していきます。
先ほど作成したFirebaseプロジェクトからRemote Configの管理画面を開きます。
スクリーンショット 2019-12-18 22.58.13.png

管理画面から、簡単にパラメータの追加が行えるので
先ほどプログラムで引数に与えたremote_string_valueのキーで設定していきます。
追加できたら右上の変更を公開を押して動作確認してみてください。
スクリーンショット 2019-12-18 22.59.37.png

さいごに

とても簡単にサーバーレスで即時にアプリの変更をすることができましたね。

ストアの規約上、なんでも変更していいというわけではないですが
A/Bテストなどではとても力を発揮すると思いますので是非使ってみてください。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした