生成された Android SDK を使用する

Firebase SQL Connect クライアント SDK を使用すると、Firebase アプリからサーバーサイドのクエリと ミューテーションを直接呼び出すことができます。SQL Connect サービスにデプロイするスキーマ、クエリ、ミューテーションを設計するのと 並行して、カスタム クライアント SDK を SQL Connect 生成します。次に、この SDK のメソッドをクライアント ロジックに統合します。

他の場所でも説明したように、SQL Connect クエリとミューテーションはクライアント コードによって送信され、 サーバーで実行されるわけではないことに注意してください。代わりに、デプロイされると、SQL Connect オペレーションは Cloud Functions のように サーバーに保存されます。つまり、既存のユーザー(古いアプリ バージョンなど)に影響を与えないようにするには、対応するクライアントサイドの変更をデプロイする必要があります。

そのため、SQL Connect には、サーバーにデプロイされたスキーマ、クエリ、ミューテーションのプロトタイプを作成できる開発環境と ツールが用意されています。 また、プロトタイプ作成中にクライアントサイドの SDK が自動的に生成されます。

サービスとクライアント アプリの更新を繰り返すと、サーバーサイドとクライアントサイドの両方の更新をデプロイできるようになります。

クライアント開発ワークフローとは

スタートガイドに沿って進めた場合は、スタートガイドに沿って進めた場合は、 全体的な開発フローについて説明しました。SQL Connectこのガイドでは、スキーマから Android SDK を生成し、クライアントのクエリとミューテーションを操作する方法について詳しく説明します。

まとめると、生成された Android SDK をクライアント アプリで使用するには、次の前提条件を満たす必要があります。

  1. Android アプリに Firebase を追加する。
  2. Gradle で SQL Connect を依存関係として構成する。
  3. Kotlin シリアル化 Gradle プラグインと Gradle 依存関係を追加する。

その後の操作は次のとおりです。

  1. アプリのスキーマを開発する。
  2. SDK の生成を設定する。

  3. クライアント コードを初期化してライブラリをインポートする

  4. クエリとミューテーションの呼び出しを実装する

  5. エミュレータSQL Connectを設定して使用し、反復処理を行う 。

Kotlin SDK を生成する

アプリで SQL Connect 生成 SDK を設定するには、Firebase CLI を使用します。 init コマンドは、現在のフォルダ内のすべてのアプリを検出し、生成された SDK を自動的にインストールします。

firebase init dataconnect:sdk

プロトタイプ作成中に SDK を更新する

SQL Connect VS Code 拡張機能がインストールされている場合、生成された SDK は常に最新の状態に保たれます。

SQL Connect VS Code 拡張機能を使用しない場合は、Firebase CLI を使用して、生成された SDK を最新の状態に保つことができます。

firebase dataconnect:sdk:generate --watch

ビルド パイプラインで SDK を生成する

Firebase CLI を使用して、CI/CD ビルドプロセスで SQL Connect SDK を生成できます。

firebase dataconnect:sdk:generate

クライアント コードを設定する

SQL Connect をクライアント コードに組み込む

SQL Connect と生成された SDK を使用するようにクライアント コードを設定するには、 まず Firebase の標準設定 の手順に沿って操作します

次に、app/build.gradle.ktsplugins セクションに以下を追加します。

// The Firebase team tests with version 1.8.22; however, other 1.8 versions,
// and all newer versions are expected work too.
kotlin("plugin.serialization") version "1.8.22" // MUST match the version of the Kotlin compiler

次に、app/build.gradle.ktsdependencies セクションに以下を追加します。

implementation(platform("com.google.firebase:firebase-bom:34.12.0"))
implementation("com.google.firebase:firebase-dataconnect")
implementation("com.google.firebase:firebase-auth") // Optional
implementation("com.google.firebase:firebase-appcheck") // Optional
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3") // Newer versions should work too
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:1.5.1") // Newer versions should work too

SQL Connect Android SDK を初期化する

SQL Connect インスタンスの設定に使用した情報(Firebase コンソールの SQL Connect タブで確認できます)を使用して、SQL Connect インスタンスを初期化します。

ConnectorConfig オブジェクト

SDK にはコネクタ構成オブジェクトが必要です。

このオブジェクトは、dataconnect.yamlserviceIdlocationconnector.yamlconnectorId から自動的に生成されます。

コネクタ インスタンスを取得する

構成オブジェクトを設定したら、SQL Connect コネクタ インスタンスを取得します。コネクタのコードは、 SQL Connect エミュレータによって生成されます。connector.yaml で指定されているように、コネクタ名が movies で Kotlin パッケージが com.myapplication の場合は、次の呼び出しでコネクタ オブジェクトを取得します。

val connector = com.myapplication.MoviesConnector.instance

Android SDK のクエリとミューテーションを使用する

コネクタ オブジェクトを使用すると、GraphQL ソースコードで定義されているクエリとミューテーションを実行できます。コネクタに次のオペレーションが定義されているとします。

mutation createMovie($title: String!, $releaseYear: Int!, $genre: String!, $rating: Int!) {
  movie_insert(data: {
    title: $title
    releaseYear: $releaseYear
    genre: $genre
    rating: $rating
  })
}

query getMovieByKey($key: Movie_Key!) {
  movie(key: $key) { id title }
}

query listMoviesByGenre($genre: String!) {
  movies(where: {genre: {eq: $genre}}) {
    id
    title
  }
}

次のようにして映画を作成して取得できます。

val connector = MoviesConnector.instance

val addMovieResult1 = connector.createMovie.execute(
  title = "Empire Strikes Back",
  releaseYear = 1980,
  genre = "Sci-Fi",
  rating = 5
)

val movie1 = connector.getMovieByKey.execute(addMovieResult1.data.key)

println("Empire Strikes Back: ${movie1.data.movie}")

複数の映画を取得することもできます。

val connector = MoviesConnector.instance

val addMovieResult2 = connector.createMovie.execute(
  title="Attack of the Clones",
  releaseYear = 2002,
  genre = "Sci-Fi",
  rating = 5
)

val listMoviesResult = connector.listMoviesByGenre.execute(genre = "Sci-Fi")

println(listMoviesResult.data.movies)

クエリの execute() メソッドの呼び出しを使用して新しいクエリ結果が取得された場合にのみ結果を生成する Flow を収集することもできます。

val connector = MoviesConnector.instance

connector.listMoviesByGenre.flow(genre = "Sci-Fi").collect { data ->
  println(data.movies)
}

connector.createMovie.execute(
  title="A New Hope",
  releaseYear = 1977,
  genre = "Sci-Fi",
  rating = 5
)

connector.listMoviesByGenre.execute(genre = "Sci-Fi") // will cause the Flow to get notified

列挙型フィールドの変更を処理する

アプリのスキーマには列挙型を含めることができ、 GraphQL クエリでアクセスできます

アプリのデザインが変更されると、サポートされる新しい列挙値を追加できます。たとえば、アプリケーションのライフサイクルの後半で、AspectRatio 列挙型に FULLSCREEN 値を追加するとします。

SQL Connect ワークフローでは、ローカル開発ツールを使用して クエリと SDK を更新できます。

ただし、クライアントの更新バージョンをリリースする前に、デプロイ済みの古いクライアントが破損する可能性があります。

復元力のある実装例

生成された SDK は、不明な値の処理を強制します。これは、顧客のコードで EnumValue オブジェクトをアンラップする必要があるためです。このオブジェクトは、既知の列挙値の場合は EnumValue.Known、不明な値の場合は EnumValue.Unknown です。

val result = connector.listMoviesByAspectRatio.execute(AspectRatio.WIDESCREEN)
val encounteredAspectRatios = mutableSetOf<String>()

result.data.movies
  .mapNotNull { it.otherAspectRatios }
  .forEach { otherAspectRatios ->
    otherAspectRatios
      .filterNot { it.value == AspectRatio.WIDESCREEN }
      .forEach {
        when (it) {
          is EnumValue.Known -> encounteredAspectRatios.add(it.value.name)
          is EnumValue.Unknown ->
            encounteredAspectRatios.add("[unknown ratio: ${it.stringValue}]")
        }
      }
  }

println(
  "Widescreen movies also include additional aspect ratios: " +
    encounteredAspectRatios.sorted().joinToString()
)

クライアントサイド キャッシュを有効にする

SQL Connect には、クライアントサイド キャッシュ機能(オプション)があります。この機能を有効にするには、connector.yaml ファイルを編集します。この機能を有効にすると、生成されたクライアント SDK はクエリ レスポンスをローカルにキャッシュします。これにより、アプリが送信するデータベース リクエストの数を減らし、ネットワークが中断された場合でもアプリのデータベース依存部分が動作するようにできます。

クライアントサイド キャッシュを有効にするには、コネクタ構成にクライアント キャッシュ構成を追加します。

generate:
  kotlinSdk:
    outputDir: "../android"
    package: "com.google.firebase.dataconnect.generated"
    clientCache:
      maxAge: 5s
      storage: persistent

この構成には 2 つのパラメータがあります。どちらも省略可能です。

  • maxAge: キャッシュされたレスポンスがクライアント SDK で新しい値を取得するまでの最大経過時間。例: "0"、"30s"、"1h30m"。

    maxAge のデフォルト値は 0 です。これは、レスポンスがキャッシュされるものの、クライアント SDK は常に新しい値を取得することを意味します。キャッシュされた値は、execute()CACHE_ONLY が指定されている場合にのみ使用されます。

  • storage: クライアント SDK は、レスポンスを persistent ストレージまたは memory にキャッシュするように構成できます。persistent ストレージにキャッシュされた結果は、アプリの再起動後も保持されます。Android SDK では、デフォルトは persistent です。

コネクタのキャッシュ構成を更新したら、クライアント SDK を再生成してアプリを再ビルドします。これにより、execute() はキャッシュ レスポンスをキャッシュし、構成したポリシーに従ってキャッシュされた値を使用します。通常、この処理は自動的に行われるため、追加の操作は不要です。ただし、次の点に注意してください。

  • execute() のデフォルトの動作は上記のとおりです。クエリの結果がキャッシュされ、キャッシュされた値が maxAge より古くない場合は、キャッシュされた値を使用します。このデフォルトの動作は PREFER_CACHE ポリシーと呼ばれます。

    execute() の個々の呼び出しに、キャッシュされた値のみを処理する(CACHE_ONLY)か、サーバーから新しい値を無条件にフェッチする(SERVER_ONLY)かを指定することもできます。

    val queryResult = queryRef.execute(QueryRef.FetchPolicy.CACHE_ONLY)
    
    val queryResult = queryRef.execute(QueryRef.FetchPolicy.SERVER_ONLY)
    

    Android アプリのプロトタイプを作成してテストする

    ローカル エミュレータを使用するようにクライアントをインストルメントする

    SQL Connect エミュレータは、 SQL Connect VS Code 拡張機能または CLI から使用できます。

    エミュレータに接続するようにアプリをインストルメントする方法は、どちらのシナリオでも同じです。

    val connector = MoviesConnector.instance
    
    // Connect to the emulator on "10.0.2.2:9399"
    connector.dataConnect.useEmulator()
    
    // (alternatively) if you're running your emulator on non-default port:
    connector.dataConnect.useEmulator(port = 9999)
    
    // Make calls from your app
    
    

    本番環境リソースに切り替えるには、エミュレータに接続するための行をコメントアウトします。

    SQL Connect SDK の SQL 型

    SQL Connect サーバーは、一般的な GraphQL データ型とカスタム GraphQL データ型を表します。これらは SDK で次のように表されます。

    SQL Connect Kotlin
    文字列 文字列
    Int Int(32 ビット整数)
    浮動小数点数 倍精度浮動小数点数(64 ビット浮動小数点数)
    ブール値 ブール値
    UUID java.util.UUID
    日付 com.google.firebase.dataconnect.LocalDate(16.0.0-beta03 までは java.util.Date)
    タイムスタンプ com.google.firebase.Timestamp
    Int64 長い
    すべて com.google.firebase.dataconnect.AnyValue