Firebase と App Engine フレキシブル環境を使用して Android アプリを作成

このチュートリアルでは、Firebase を使用したバックエンド データ ストレージやリアルタイム同期、ユーザー イベントロギングに対応するモバイルアプリの開発方法をご紹介します。Google Cloud Platform(GCP)App Engine フレキシブル環境で動作する Java サーブレットが、Firebase に保存された新しいユーザーログをリッスンして処理します。

このチュートリアルの手順では、FirebaseApp Engine フレキシブル環境を使用して目的のモバイルアプリを開発する方法を説明します。

ユーザーデータの処理またはイベントのオーケストレーションがアプリ側で必要な場合は、App Engine フレキシブル環境を利用して Firebase を拡張すれば、リアルタイムの自動データ同期が利用できます。

Playchat サンプルアプリによりチャット メッセージが Firebase Realtime Database に保存され、デバイス間で自動的に同期されます。Playchat は、ユーザー イベントログも Firebase に書き込みます。データベースによるデータの同期方法の詳細については、Firebase ドキュメントの仕組みをご覧ください。

次の図に、Playchat クライアントのアーキテクチャを示します。

Playchat クライアント アーキテクチャ

App Engine フレキシブル環境で動作する一連の Java サーブレットが、リスナーとして Firebase に登録されます。これらのサーブレットが新しいユーザーイベント ログに応答し、ログデータを処理します。サーブレットはトランザクションを使用します。これにより、各ユーザーイベント ログを処理するサーブレットがただ 1 つであることが保証されます。

次の図に、Playchat サーバーのアーキテクチャを示します。

Playchat サーバー アーキテクチャ

アプリとサーブレット間の通信は、以下の 3 つの処理で発生します。

  • 新しいユーザーが Playchat にログインし、アプリがそのユーザーのロギング サーブレットをリクエストするために Firebase Realtime Database の /inbox/ の下にエントリを追加したとき。

  • いずれかのサーブレットが、このエントリの値を自分のサーブレット ID に変更して割り当てを受け入れたとき。このサーブレットは、自分以外のサーブレットが値を変更できないことを保証するために Firebase トランザクションを使用します。値が更新されると、他のすべてのサーブレットはリクエストを無視します。

  • ユーザーがログインまたはログアウトするか、新しいチャネルに切り替えたとき。このアクションを Playchat が /inbox/[SERVLET_ID]/[USER_ID]/ に記録します。ここで、[SERVLET_ID] はサーブレット インスタンスの ID であり、[USER_ID] はユーザーを表すハッシュ値です。

  • サーブレットが Inbox を監視して新しいエントリのログデータを収集するとき。

このサンプルアプリでは、ログデータがサーブレットによりローカルでコピーされ、ウェブページに表示されます。このアプリの本番環境バージョンでは、ログデータをサーブレットで処理する目的や、保存および分析の目的で Cloud StorageCloud BigtableBigQuery にコピーできます。

目標

このチュートリアルでは、以下の手順を紹介します。

  • Android アプリである Playchat のビルド手順。このアプリはデータを Firebase Realtime Database に保存します。

  • App Engine フレキシブル環境での Java サーブレットの実行手順。このサーブレットは、Firebase に接続し、Firebase に保存されたデータが変更されたときに通知を受け取ります。

  • 上記の 2 つのコンポーネントを使用して、分散型のストリーミング バックエンド サービスをビルドしてログデータを収集し、処理する手順。

費用

Firebase の使用は特定条件のもとで無料です。これらのサービスの使用量が Firebase 無料プランで指定された制限未満である場合、Firebase を使用しても料金はかかりません。

App Engine フレキシブル環境内のインスタンスについては、基盤となる Google Compute Engine 仮想マシンに対して費用がかかります。

始める前に

以下のソフトウェアをインストールします。

コマンドラインから次のコマンドを実行して、Cloud SDK の App Engine Java コンポーネントをインストールします。

gcloud components install app-engine-java

サンプルコードのクローンの作成

  1. フロントエンド クライアント アプリのコードのクローンを作成します。

    git clone https://github.com/GoogleCloudPlatform/firebase-android-client
    
  2. バックエンド サーブレットのコードのクローンを作成します。

    git clone https://github.com/GoogleCloudPlatform/firebase-appengine-backend
    

アプリ用 SHA-1 フィンガープリントの生成

Google ログインでクライアント アプリを認証するには、証明書の SHA-1 フィンガープリントを用意する必要があります。このチュートリアルでは、デバッグ キーストアを使用します。キーストア フィンガープリントのリリース バージョンを作成する方法については、ユーザー独自のクライアントの認証をご覧ください。

  • 使用するデバッグ キーストアの SHA-1 を作成します。

    keytool -list -v \
    -alias androiddebugkey -keystore ~/.android/debug.keystore
    

Firebase プロジェクトの作成

  1. Firebase アカウントを作成するか、既存のアカウントにログインします。

  2. [プロジェクトを追加] をクリックします。

  3. 初めて登録する場合は、[プロジェクトを作成] をクリックします。

  4. [プロジェクト名] に「Playchat」と入力します。

  5. 残りの設定手順を行い、[プロジェクトの作成] をクリックします。

    • このプロジェクトでは Google アナリティクスを有効にする必要はありません。
  6. ウィザードでプロジェクトがプロビジョニングされたら、[続行] をクリックします。

  7. プロジェクトの [プロジェクトの概要] ページで 設定)をクリックし、[プロジェクトの設定] をクリックします。

  8. Android アイコンをクリックすると、[Android アプリに Firebase を追加する] ページが表示されます。

  9. [Android パッケージ名] に「com.google.cloud.solutions.flexenv」と入力します。

  10. [デバッグ用の署名証明書 SHA-1] に、以前のセクションで生成した SHA-1 値を入力します。

  11. [アプリの登録] をクリックします。

  12. 構成ファイルのダウンロードの手順に沿って、google-services.json ファイルをプロジェクトに追加します。

  13. [構成ファイルのダウンロード] で [次へ] をクリックします。

  14. プロジェクト レベルとアプリレベルの build.gradle ファイルに対しての推奨される変更をメモします。

  15. [Firebase SDK の追加] で [次へ] をクリックします。

  16. [アプリを実行してインストールを確認] セクションで [このステップをスキップ] をクリックします。

Realtime Database の作成

  1. Firebase コンソールでプロジェクトを選択します。

  2. コンソールの左側のメニューで、[開発] グループの [データベース] を選択します。

  3. [データベース] ページの [Realtime Database] セクションで [データベースを作成] をクリックします。

  4. [Realtime Database のセキュリティ ルール] ダイアログで、[テストモードで開始] を選択し、[有効化] をクリックします。

    この操作により、Firebase に保存したデータが表示されます。このチュートリアルの後のステップで、ウェブページを再度閲覧し、クライアント アプリとバックエンド サーブレットにより追加、変更されたデータを確認します。

  5. データベースの [ルール] タブで、読み取り / 書き込みのセキュリティ ルールがあることを確認します。例:

    {
      "rules": {
        ".read": true,
        ".write": true
      }
    }
    
  6. プロジェクトの Firebase URL をメモします。これは、リンクアイコンの横に https://[FIREBASE_PROJECT_ID].firebaseio.com/ という形式で表示されています。

Firebase プロジェクトの Google 認証の有効化

Firebase プロジェクトに接続するために、さまざまなログイン プロバイダを構成できます。このチュートリアルでは、ユーザーが Google アカウントを使用してログインできるように認証を設定する方法について説明します。

  1. Firebase コンソールの左側のメニューで、[開発] グループの [認証] をクリックします。

  2. [ログイン方法を設定] をクリックします。

  3. [Google] を選択し、[有効にする] をオンにして、[保存] をクリックします。

Firebase プロジェクトへのサービス アカウントの追加

バックエンド サーブレットでは、ログインに Google アカウントを使用しません。代わりに、サービス アカウントを使用して Firebase に接続します。以下の手順では、Firebase に接続するサービス アカウントを作成して、サービス アカウントの認証情報をサーブレットのコードに追加する方法について説明します。

  1. Firebase コンソールの左側のメニューで、Playchat プロジェクト ホームの横にある [設定] の歯車アイコンを選択し、[プロジェクトの設定] を選択します。

  2. [サービス アカウント] を選択し、[サービス アカウント権限の管理] リンクをクリックします。

  3. [サービス アカウントを作成] をクリックします。

  4. 以下の設定を構成します。

    1. [サービス アカウント名] に「playchat-servlet」と入力し、[作成] をクリックします。
    2. [ロールを選択] で、[プロジェクト] > [オーナー] の順に選択し、[続行] をクリックします。

    3. [完了] をクリックします。

  5. 作成したサービス アカウントをクリックし、[キーを追加]、[新しいキーを作成] の順にクリックします。

  6. [キーのタイプ] の横にある [JSON] をクリックし、[作成] をクリックしてキーをダウンロードします。

  7. サービス アカウント用のダウンロードした JSON キーファイルを、src/main/webapp/WEB-INF/ ディレクトリのバックエンド サービス プロジェクト firebase-appengine-backend に保存します。ファイル名の形式は Playchat-[UNIQUE_ID].json です。

  8. src/main/webapp/WEB-INF/web.xml を編集して、初期化パラメータを以下のように設定します。

    • JSON_FILE_NAME を、ダウンロードした JSON キーファイルの名前に置き換えます。

    • FIREBASE_URL を、以前にメモした Firebase URL で置き換えます。

      <init-param>
        <param-name>credential</param-name>
        <param-value>/WEB-INF/JSON_FILE_NAME</param-value>
      </init-param>
      <init-param>
        <param-name>databaseUrl</param-name>
        <param-value>FIREBASE_URL</param-value>
      </init-param>
      

Cloud Platform プロジェクトの課金と API の有効化

Cloud Platform でバックエンド サービスを実行するには、プロジェクトの課金と API を有効にする必要があります。Cloud Platform プロジェクトは、Firebase プロジェクトの作成で作成したプロジェクトと同じものであり、同じプロジェクト ID が付いています。

  1. Cloud Platform Console で Playchat プロジェクトを選択します。

    プロジェクト ページに移動

  2. Google Cloud プロジェクトに対して課金が有効になっていることを確認します。プロジェクトに対して課金が有効になっていることを確認する方法を学習する

  3. App Engine Admin API and Compute Engine API API を有効にします。

    API を有効にする

バックエンド サービスの構築とデプロイ

このサンプルでは、バックエンド サービスは Docker 構成を使用してホスティング環境を指定します。このようにカスタマイズするには、App Engine のスタンダード環境ではなくフレキシブル環境を使用する必要があります。

バックエンド サーブレットを構築して App Engine フレキシブル環境にデプロイするには、Google App Engine Maven プラグインを使用できます。このプラグインは、このサンプルに含まれている Maven ビルドファイルですでに指定されています。

プロジェクトの設定

Maven でバックエンド サーブレットが正しくビルドされるようにするには、サーブレットのリソースを起動する Google Cloud Platform(GCP)プロジェクトを Maven に指定する必要があります。GCP プロジェクトと Firebase プロジェクトの ID は同じです。

  1. gcloud ツールが GCP へのアクセスに使用する、認証情報を入力します。

    gcloud auth login
    
  2. 次のコマンドを実行して、プロジェクトを Firebase プロジェクトに設定します。[FIREBASE_PROJECT_ID] は、以前にメモした Firebase プロジェクト ID の名前に置き換えます。

    gcloud config set project [FIREBASE_PROJECT_ID]
    
  3. 構成を表示して、プロジェクトが設定されたことを確認します。

    gcloud config list
    
  4. App Engine を初めて使用する場合は、App Engine アプリを初期化します

    gcloud app create
    

(省略可)ローカル サーバーでのサービスの実行

新しいバックエンド サービスを開発する際には、App Engine にデプロイする前にローカルでそのサービスを実行するのが有効です。これにより、変更の迅速な反復適用が可能になり、App Engine にデプロイする際のオーバーヘッドが回避されます。

ローカルでサーバーを実行する場合、Docker の構成は使用されず、App Engine 環境では実行されません。代わりに、Maven がすべての依存関係ライブラリをローカルにインストールし、Jetty ウェブサーバー上でアプリが実行されます。

  1. firebase-appengine-backend ディレクトリで、次のコマンドを使用してバックエンド モジュールをローカルで構築して実行します。

    mvn clean package appengine:run
    

    ~/google-cloud-sdk 以外のディレクトリに gcloud コマンドライン ツールをインストールした場合は、次に示すようにコマンドにインストール パスを追加します([PATH_TO_TOOL] の部分をカスタムパスで置き換えてください)。

    mvn clean package appengine:run -Dgcloud.gcloud_directory=[PATH_TO_TOOL]
    
  2. アプリケーション "Python.app" で受信ネットワーク接続を受け入れますか?」というメッセージが表示された場合は、[Allow] を選択します。

デプロイの終了後、http://localhost:8080/printLogs を開いて、バックエンド サービスが実行されていることを確認します。ウェブページに、「Inbox :」に続いて 16 桁の ID が表示されます。これは、ローカルマシンで実行されているサーブレットの Inbox ID です。

ページを更新してもこの ID は変わりません。ローカル サーバーは単一のサーブレット インスタンスを起動するからです。これはテストの際に役立ちます。Firebase Realtime Database にはサーブレット ID が 1 つしか保存されないためです。

ローカル サーバーをシャットダウンするには、Ctrl+C と入力します。

App Engine フレキシブル環境へのサービスのデプロイ

App Engine フレキシブル環境でバックエンド サービスを実行すると、App Engine は /firebase-appengine-backend/src/main/webapp/Dockerfiles の構成を使用して、サービスが実行されるホスティング環境を構築します。フレキシブル環境は複数のサーブレット インスタンスを起動し、需要に応じてその規模を拡大または縮小します。

  • firebase-appengine-backend ディレクトリで、次のコマンドを使用してバックエンド モジュールをローカルで構築して実行します。

    mvn clean package appengine:deploy
    
    mvn clean package appengine:deploy -Dgcloud.gcloud_directory=[PATH_TO_GCLOUD]
    

ビルドを実行すると、「Sending build context to Docker daemon…」と表示されます。上記のコマンドにより、Docker の構成がアップロードされ、App Engine フレキシブル環境に設定されます。

デプロイが終了したら、https://[FIREBASE_PROJECT_ID].appspot.com/printLogs を開きます。ここで、[FIREBASE_PROJECT_ID]Firebase プロジェクトの作成で割り当てられた ID です。ウェブページに、「Inbox :」に続いて 16 桁の ID が表示されます。これは、App Engine フレキシブル環境で実行されているサーブレットの Inbox ID です。

ページを更新すると、この ID は定期的に変わります。これは、受信したクライアントからのリクエストを処理するために、App Engine が複数のサーブレット インスタンスを起動するためです。

Android アプリへの Firebase と Google Play 開発者サービスの追加

クライアント アプリは Firebase Realtime Database を使用して、メッセージの保存と同期や、ユーザーイベント ログの記録を行います。クライアント アプリは Google Play 開発者サービスを使用して、Google アカウントを所有するユーザーを認証します。

  1. Android Studio で、[Tools] > [SDK Manager] を選択します。

  2. [SDK Tools] タブを選択します。

  3. [Google Play services] がまだ選択されていない場合は選択します。

  4. [OK] をクリックしてインストールします。

  5. [File] > [Open…] の順に選択して、firebase-android-client ディレクトリを選択します。

  6. Gradle プロジェクト情報にビルドの終了が表示されるまで待ちます。Gradle ラッパーを使用するように求められたら、[OK] をクリックします。

  7. Firebase プロジェクトの作成でメモした、プロジェクト レベルとアプリレベルの build.gradle ファイルの変更内容が、サンプルコードにすでに反映されています。

Android アプリの実行とテスト

  1. Android Studio で firebase-android-client プロジェクトを開き、[Run] > [Run 'app'] を選択します。

  2. Google API を使用して Android 6.0 を実行するデバイスまたはエミュレータをテストデバイスとして選択します。

  3. アプリがデバイスに読み込まれたら、Google アカウントでログインします。

    Playchat にログイン

  4. PlayChat のタイトルの左にあるメニューをクリックし、[books] チャンネルを選択します。

    チャンネルを選択

  5. メッセージを入力します。

    メッセージを送信

  6. 入力すると、Playchat アプリがメッセージを Firebase Realtime Database に保存します。Firebase はデータベースに保存されたデータを端末間で同期します。Playchat を実行するデバイスでは、ユーザーが [books] チャンネルを選択すると新しいメッセージが表示されます。

    メッセージを送信

データの検証

Playchat アプリを使ってユーザー イベントをいくつか生成した後に、サーブレットがリスナーとして登録され、ユーザー イベントログが収集されていることを確認します。

アプリの Firebase Realtime Database を開きます。ここで、[FIREBASE_PROJECT_ID]Firebase プロジェクトの作成で割り当てられた ID です。

https://console.firebase.google.com/project/[FIREBASE_PROJECT_ID]/database/data

Firebase Realtime Database の最下部(/inbox/ の下)に、接頭辞 client- の付いたノードのグループが表示され、その後に、ユーザー アカウントのログインを表すランダム生成のキーが続きます。この例の最後の項目 client-1240563753 の後には、ユーザーのログイベントを現在リッスンしているサーブレットを示す 16 桁の ID が続きます(この例では、0035806813827987)。

Firebase Realtime Database に保存されたデータ

すぐ上の、/inbox/ データの場所の下に、現在割り当てられているすべてのサーブレットのサーブレット ID が表示されます。この例では、ログを収集しているサーブレットは 1 つだけです。/inbox/[SERVLET_IDENTIFIER] の下には、アプリによりそのサーブレットに書き込まれたユーザーログが示されます。

バックエンド サービスの App Engine ページ(https://[FIREBASE_PROJECT_ID].appspot.com/printLogs)を開きます。ここで、[FIREBASE_PROJECT_ID]Firebase プロジェクトの作成で割り当てられた ID です。このページには、生成されたユーザー イベントを記録するサーブレットの ID が表示されます。また、そのサーブレットの Inbox ID の下にも、記録されたイベントのログエントリが表示されます。

コードの確認

Android アプリである Playchat は、FirebaseLogger というクラスを定義します。これは、Firebase Realtime Database にユーザー イベント ログを書き込むために使用されます。


import com.google.cloud.solutions.flexenv.common.LogEntry;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;

/*
 * FirebaseLogger pushes user event logs to a specified path.
 * A backend servlet instance listens to
 * the same key and keeps track of event logs.
 */
class FirebaseLogger {
    private final DatabaseReference logRef;

    FirebaseLogger(String path) {
        logRef = FirebaseDatabase.getInstance().getReference().child(path);
    }

    public void log(String tag, String message) {
        LogEntry entry = new LogEntry(tag, message);
        logRef.push().setValue(entry);
    }

}

新しいユーザーがログインすると、Playchat は requestLogger 関数を呼び出して Firebase Realtime Database の /inbox/ に新しいエントリを追加します。また、リスナーを設定して、サーブレットが割り当てを受け入れてエントリの値を更新したときに、Playchat が応答できるようにします。

サーブレットが値を更新すると、Playchat はリスナーを削除して、「Signed in」のログをサーブレットの Inbox に書き込みます。

/*
 * Request that a servlet instance be assigned.
 */
private void requestLogger(final LoggerListener loggerListener) {
    final DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference();
    databaseReference.child(IBX + "/" + inbox).addListenerForSingleValueEvent(new ValueEventListener() {
        public void onDataChange(@NonNull DataSnapshot snapshot) {
            if (snapshot.exists() && snapshot.getValue(String.class) != null) {
                firebaseLoggerPath = IBX + "/" + snapshot.getValue(String.class) + "/logs";
                fbLog = new FirebaseLogger(firebaseLoggerPath);
                databaseReference.child(IBX + "/" + inbox).removeEventListener(this);
                loggerListener.onLoggerAssigned();
            }
        }

        public void onCancelled(@NonNull DatabaseError error) {
            Log.e(TAG, error.getDetails());
        }
    });

    databaseReference.child(REQLOG).push().setValue(inbox);
}

バックエンド サービス側では、サーブレット インスタンスが起動されると、MessageProcessorServlet.javainit(ServletConfig config) 関数が Firebase Realtime Database に接続し、リスナーを /inbox/ データのロケーションに追加します。

新しいエントリが /inbox/ データのロケーションに追加されると、サーブレットはその値を自身の ID に変更します。また、そのユーザーログの処理の割り当てをサーブレットが受け入れたことを示す信号が Playchat アプリに送信されます。サーブレットは Firebase のトランザクションを使用することで、値を変更して割り当てを受け入れるサーブレットがただ 1 つであることを保証します。

/*
 * Receive a request from a client and reply back its inbox ID.
 * Using a transaction ensures that only a single servlet instance replies
 * to the client. This lets the client know to which servlet instance
 * send consecutive user event logs.
 */
firebase.child(REQLOG).addChildEventListener(new ChildEventListener() {
  public void onChildAdded(DataSnapshot snapshot, String prevKey) {
    firebase.child(IBX + "/" + snapshot.getValue()).runTransaction(new Transaction.Handler() {
      public Transaction.Result doTransaction(MutableData currentData) {
        // Only the first servlet instance writes its ID to the client inbox.
        if (currentData.getValue() == null) {
          currentData.setValue(inbox);
        }
        return Transaction.success(currentData);
      }

      public void onComplete(DatabaseError error, boolean committed, DataSnapshot snapshot) {}
    });
    firebase.child(REQLOG).removeValue();
  }
  // ...
});

サーブレットは、ユーザーのイベントログ処理の割り当てを受け入れた後、Playchat アプリが新しいログファイルをサーブレットの Inbox に書き込んだことを検出するリスナーを追加します。Inbox への書き込みを検出すると、サーブレットは Firebase Realtime Database から新しいログデータを取得します。

/*
 * Initialize user event logger. This is just a sample implementation to
 * demonstrate receiving updates. A production version of this app should
 * transform, filter, or load to another data store such as Google BigQuery.
 */
private void initLogger() {
  String loggerKey = IBX + "/" + inbox + "/logs";
  purger.registerBranch(loggerKey);
  firebase.child(loggerKey).addChildEventListener(new ChildEventListener() {
    public void onChildAdded(DataSnapshot snapshot, String prevKey) {
      if (snapshot.exists()) {
        LogEntry entry = snapshot.getValue(LogEntry.class);
        logs.add(entry);
      }
    }

    public void onCancelled(DatabaseError error) {
      localLog.warning(error.getDetails());
    }

    public void onChildChanged(DataSnapshot arg0, String arg1) {}

    public void onChildMoved(DataSnapshot arg0, String arg1) {}

    public void onChildRemoved(DataSnapshot arg0) {}
  });
}

クリーンアップ

このチュートリアルで使用するリソースについて、Google Cloud Platform アカウントに課金されないようにする手順は次のとおりです。

Cloud Platform と Firebase プロジェクトを削除する

課金を停止する最も簡単な方法は、このチュートリアルで作成したプロジェクトを削除することです。Firebase コンソールでプロジェクトを作成した場合でも、Cloud Platform Console でプロジェクトを削除できます。なぜなら、Firebase プロジェクトと Cloud Platform プロジェクトは同一であるからです。

  1. Cloud Console で [リソースの管理] ページに移動します。

    [リソースの管理] ページに移動

  2. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  3. ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。

App Engine アプリのデフォルト以外のバージョンを削除する

Cloud Platform プロジェクトと Firebase プロジェクトを削除しない場合は、App Engine フレキシブル環境のデフォルト バージョンではないアプリを削除すれば、課金をいくらか減らすことができます。

  1. Cloud Console で、App Engine の [バージョン] ページに移動します。

    [バージョン] ページに移動

  2. デフォルト以外で削除するアプリのバージョンのチェックボックスをオンにします。
  3. [削除] をクリックして、アプリのバージョンを削除します。

次のステップ

  • データの解析とアーカイブ - このサンプルでは、サーブレットはログデータをメモリ内のみに保存します。このサンプルの機能を拡張するには、Cloud StorageCloud BigtableGoogle Cloud Dataflow、および BigQuery などのサービスを使用して、サーブレットによってデータがアーカイブ、変換、分析されるようにします。

  • サーブレット間での負荷の均等分散 - App Engine では、自動スケーリングと手動スケーリングの両方が使用できます。自動スケーリングでは、フレキシブル環境でワークロードの変化が検出されると、クラスタで VM が追加または削除されます。手動スケーリングでは、トラフィックを処理するインスタンスの数を固定値で指定します。スケーリングの構成方法については、App Engine ドキュメントのサービス スケーリング設定をご覧ください。

    ユーザー アクティビティ ログは、Firebase Realtime Database にアクセスしてサーブレットに割り当てられるため、ワークロードが均等に分散されないことがあります。たとえば、特定のサーブレットが他のサーブレットよりも多くのユーザーイベント ログを処理する場合があります。

    それぞれの VM のワークロードを個別に制御するワークロード マネージャーを実装すれば効率が良くなります。このようなワークロード分散処理は、秒単位のリクエストのロギングや、同時クライアント数の監視といった指標に基づいて実行されます。

  • 未処理のユーザーイベント ログの回復 - このサンプルの実装内容では、サーブレット インスタンスがクラッシュしても、そのインスタンスに関連付けられたクライアント アプリは、ログイベントを Firebase Realtime Database のサーブレットの Inbox に送信し続けます。アプリの本番環境バージョンでは、バックエンド サービスでこの状況を検出して、未処理のユーザーイベント ログを回復する必要があります。

  • Cloud AI プロダクトを使用した追加機能の実装 - Cloud AI プロダクトおよびサービスを使用して ML ベースの機能を実装する方法です。たとえば、このサンプルの実装内容を拡張して、Speech-to-Text APITranslation APIText-to-Speech API を組み合わせた音声翻訳機能を実装できます。詳しくは、Android アプリに音声翻訳機能を追加するをご覧ください。