Firebase SQL Connect クライアント SDK を使用すると、Firebase アプリからサーバーサイドのクエリとミューテーションを直接呼び出すことができます。SQL Connect サービスにデプロイするスキーマ、クエリ、ミューテーションを設計するのと並行して、カスタム クライアント SDK を生成します。次に、この SDK のメソッドをクライアント ロジックに統合します。
別の場所でも説明したように、SQL Connect クエリとミューテーションはクライアント コードによって送信され、サーバーで実行されるわけではないことに注意してください。代わりに、デプロイ時に SQL Connect オペレーションは Cloud Functions などのサーバーに保存されます。つまり、既存のユーザー(古いバージョンのアプリなど)を壊さないように、対応するクライアントサイドの変更をデプロイする必要があります。
そのため、SQL Connect には、サーバーにデプロイされたスキーマ、クエリ、ミューテーションのプロトタイプを作成できるデベロッパー環境とツールが用意されています。また、プロトタイピング中にクライアントサイド SDK を自動的に生成します。
サービスアプリとクライアント アプリの更新を繰り返し行うと、サーバーサイドとクライアント サイドの両方の更新をデプロイできるようになります。
クライアント開発のワークフローとは何ですか?
スタートガイドに沿って、SQL Connect の開発フロー全体について説明しました。このガイドでは、スキーマから Android SDK を生成し、クライアント クエリとミューテーションを操作する方法について詳しく説明します。
要約すると、生成された Android SDK をクライアント アプリで使用するには、次の前提条件の手順を行います。
- Android アプリに Firebase を追加します。
- Gradle で SQL Connect を依存関係として構成します。
- Kotlin シリアル化 Gradle プラグインと Gradle 依存関係を追加します。
次に、以下のリソースをご覧ください。
- アプリのスキーマを開発します。
SDK の生成を設定します。
- SQL Connect VS Code 拡張機能の [Add SDK to app] ボタンを使用する
connector.yamlを更新する
SQL Connect エミュレータを設定して使用し、反復処理を行います。
Kotlin SDK を生成する
Firebase CLI を使用して、アプリで SQL Connect 生成 SDK を設定します。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.kts の plugins セクションに追加します。
// 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.kts の dependencies セクションに追加します。
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.yaml の serviceId と location、connector.yaml の connectorId から自動的に生成されます。
コネクタ インスタンスを取得する
構成オブジェクトを設定したら、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 は常に新しい値を取得することを意味します。キャッシュに保存された値は、CACHE_ONLYがexecute()に指定されている場合にのみ使用されます。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 ビット整数) 浮動小数点数 Double(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