Firebase SQL Connect クライアント SDK を使用すると、Firebase アプリからサーバーサイドのクエリとミューテーションを直接呼び出すことができます。SQL Connect サービスにデプロイするスキーマ、クエリ、ミューテーションを設計するのと並行して、カスタム クライアント SDK を生成します。次に、この SDK のメソッドをクライアント ロジックに統合します。
別の場所でも説明したように、SQL Connect クエリとミューテーションはクライアント コードによって送信され、サーバーで実行されるわけではないことに注意してください。代わりに、デプロイ時に SQL Connect オペレーションは Cloud Functions などのサーバーに保存されます。つまり、既存のユーザー(古いバージョンのアプリなど)を壊さないように、対応するクライアントサイドの変更をデプロイする必要があります。
そのため、SQL Connect には、サーバーにデプロイされたスキーマ、クエリ、ミューテーションのプロトタイプを作成できるデベロッパー環境とツールが用意されています。また、プロトタイピング中にクライアントサイド SDK を自動的に生成します。
サービスアプリとクライアント アプリの更新を繰り返し行うと、サーバーサイドとクライアント サイドの両方の更新をデプロイできるようになります。
クライアント開発のワークフローとは何ですか?
スタートガイドに沿って、SQL Connect の開発フロー全体について説明しました。このガイドでは、スキーマからウェブ SDK を生成し、クライアント クエリとミューテーションを操作する方法について詳しく説明します。
要約すると、生成された Web SDK をクライアント アプリで使用するには、次の前提条件の手順を行います。
- ウェブアプリに Firebase を追加します。
次に、以下のリソースをご覧ください。
- アプリのスキーマを開発します。
- JavaScript SDK を使用してクライアント コードを初期化します。
- SDK の生成を設定する:
- SQL Connect VS Code 拡張機能の [Add SDK to app] ボタンを使用します。
- JavaScript SDK の
connector.yamlを更新します。
- JavaScript SDK を使用してライブラリと生成されたコードをインポートします。
- JavaScript SDK を使用して、クエリとミューテーションの呼び出しを実装します。
- JavaScript SDK を使用して SQL Connect エミュレータを設定し、テストします。
Firebase JavaScript SDK を使用してクライアント コードを実装する
このセクションでは、Firebase JavaScript SDK を使用してクライアントを実装する方法について説明します。
React または Angular を使用している場合は、フレームワーク用の SQL Connect SDK の生成に関する代替のセットアップ手順と追加のドキュメントへのリンクをご覧ください。
アプリを初期化する
まず、標準の Firebase シーケンスを使用してアプリを初期化します。
initializeApp({...});
生成された JavaScript SDK をインストールする
Firebase CLI を使用して、アプリで SQL Connect 生成 SDK を設定します。init コマンドは、現在のフォルダ内のすべてのアプリを検出し、生成された SDK を自動的にインストールします。
firebase init dataconnect:sdk
アプリを SQL Connect サービスに接続します。
import { connectDataConnectEmulator } from 'firebase/data-connect';
import { connectorConfig } from '@dataconnect/generated';
const dataConnect = getDataConnect(connectorConfig);
// [Optionally] Configure the SDK to use Data Connect local emulator.
connectDataConnectEmulator(dataConnect, 'localhost', 9399);
プロトタイピング中に 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 インポートと、生成された特定の SDK インポートの 2 つのインポート セットが必要です。
一般的なインポートに含まれている ConnectorConfig オブジェクトに注目してください。
// general imports
import { ConnectorConfig, DataConnect, getDataConnect, QueryRef, MutationRef, QueryPromise, MutationPromise } from 'firebase/data-connect';
// generated queries and mutations from SDK
import { listMovies, ListMoviesResponse, createMovie, connectorConfig } from '@dataconnect/generated';
JavaScript SDK からクエリを使用する
生成されたコードには、事前定義されたクエリ参照がすでに含まれています。必要なのは、それらをインポートして実行するだけです。
import { executeQuery } from 'firebase/data-connect';
import { listMoviesRef } from '@dataconnect/generated';
const ref = listMoviesRef();
const { data } = await executeQuery(ref);
console.log(data.movies);
SDK のクエリ メソッドを呼び出す
これらのアクション ショートカット関数を使用した例を次に示します。
import { listMovies } from '@dataconnect/generated';
function onBtnClick() {
// This will call the generated JS from the CLI and then make an HTTP request out
// to the server.
listMovies().then(data => showInUI(data)); // == executeQuery(listMoviesRef);
}
変更を購読する
SQL Connect からリアルタイム アップデートを取得するをご覧ください。
列挙型フィールドの変更を処理する
アプリのスキーマには列挙型を含めることができ、GraphQL クエリでアクセスできます。
アプリの設計が変更されたら、サポートされている新しい列挙値を追加できます。たとえば、アプリケーションのライフサイクルの後半で、AspectRatio 列挙型に FULLSCREEN 値を追加するとします。
SQL Connect ワークフローでは、ローカル開発ツールを使用してクエリと SDK を更新できます。
ただし、クライアントの更新バージョンをリリースする前に、以前にデプロイされたクライアントが破損する可能性があります。
復元力のある実装の例
列挙値に対する switch ステートメントには常に default ブランチを追加し、列挙値と比較する if/else if ブロックには常に else ブランチを追加します。これは JavaScript/TypeScript 言語では強制されませんが、新しい列挙型値が追加された場合にクライアント コードを堅牢にする方法です。
const queryResult = await getOldestMovie();
if (queryResult.data) {
// we can use a switch statement's "default" case to check for unexpected values
const oldestMovieAspectRatio = queryResult.data.originalAspectRatio;
switch (oldestMovieAspectRatio) {
case AspectRatio.ACADEMY:
case AspectRatio.WIDESCREEN:
case AspectRatio.ANAMORPHIC:
console.log('This movie was filmed in Academy, widescreen or anamorphic aspect ratio!');
break;
default:
// the default case will catch FULLSCREEN, UNAVAILABLE or _UNKNOWN
// it will also catch unexpected values the SDK isn't aware of, such as CINEMASCOPE
console.log('This movie was was NOT filmed in Academy, widescreen or anamorphic.');
break;
}
// alternatively, we can check to see if the returned enum value is a known value
if (!Object.values(AspectRatio).includes(oldestMovieAspectRatio)) {
console.log(`Unrecognized aspect ratio: ${oldestAspectRatio}`);
}
} else {
console.log("no movies found!");
}
JavaScript SDK のミューテーションを使用する
ミューテーションには、クエリと同じ方法でアクセスできます。
import { executeMutation } from 'firebase/data-connect';
import { createMovieRef } from '@dataconnect/generated';
const { data } = await executeMutation(createMovieRef({ movie: 'Empire Strikes Back' }));
SQL Connect エミュレータに接続する
必要に応じて、次のように connectDataConnectEmulator を呼び出して SQL Connect インスタンスを渡すことで、エミュレータに接続できます。
import { connectDataConnectEmulator } from 'firebase/data-connect';
import { connectorConfig } from '@dataconnect/generated';
const dataConnect = getDataConnect(connectorConfig);
connectDataConnectEmulator(dataConnect, 'localhost', 9399);`
// Make calls from your app
本番環境リソースに切り替えるには、エミュレータへの接続に関する行をコメントアウトします。
クライアントサイド キャッシュを有効にする
SQL Connect には、クライアントサイド キャッシュ保存機能(省略可)があります。この機能を有効にするには、connector.yaml ファイルを編集します。この機能を有効にすると、生成されたクライアント SDK はクエリ レスポンスをローカルにキャッシュに保存します。これにより、アプリが作成するデータベース リクエストの数を減らし、ネットワークの可用性が中断されたときにアプリのデータベース依存部分が動作するようにできます。
クライアントサイド キャッシュ保存を有効にするには、コネクタ構成にクライアント キャッシュ保存構成を追加します。
generate:
javascriptSdk:
outputDir: ../web/
package: "@dataconnect/generated"
clientCache:
maxAge: 5s
storage: memory
この構成には 2 つのパラメータがあり、どちらも省略可能です。
maxAge: クライアント SDK が新しい値を取得する前に、キャッシュに保存されたレスポンスが保持できる最大期間。例: 「0」、「30s」、「1h30m」。maxAgeのデフォルト値は0です。これは、レスポンスがキャッシュに保存されるものの、クライアント SDK は常に新しい値を取得することを意味します。キャッシュに保存された値は、CACHE_ONLYがexecuteQuery()に指定され、subscribe()から返された初期結果が使用される場合にのみ使用されます。storage: クライアント SDK は、persistentストレージまたはmemoryのいずれかにレスポンスをキャッシュに保存するように構成できます。persistentストレージにキャッシュ保存された結果は、アプリの再起動後も保持されます。ウェブ SDK では、memoryストレージのみがサポートされています。
コネクタのキャッシュ保存構成を更新したら、クライアント SDK を再生成してアプリを再ビルドします。これにより、executeQuery() と subscribe() は、構成したポリシーに従ってレスポンスをキャッシュに保存し、キャッシュに保存された値を使用します。通常、この処理は自動的に行われるため、追加の操作は不要です。ただし、次の点にご注意ください。
executeQuery()のデフォルトの動作は上記のとおりです。クエリの結果がキャッシュに保存され、キャッシュに保存された値がmaxAgeより古くない場合は、キャッシュに保存された値を使用します。このデフォルトの動作はPREFER_CACHEポリシーと呼ばれます。executeQuery()の個々の呼び出しで、キャッシュに保存された値のみを処理する(CACHE_ONLY)か、サーバーから新しい値を無条件で取得する(SERVER_ONLY)かを指定することもできます。await executeQuery(queryRef, QueryFetchPolicy.CACHE_ONLY);await executeQuery(queryRef, QueryFetchPolicy.SERVER_ONLY);subscribe()を呼び出すと、maxAgeの設定に関係なく、キャッシュに保存されたコンテンツが存在する場合は常にすぐに返されます。executeQuery()の後続の呼び出しでは、構成されたmaxAgeに従ってリスナーに通知します。
SDK のデータ型
SQL Connect サーバーは、一般的な GraphQL データ型を表します。これらは SDK で次のように表されます。
| SQL Connect 型 | TypeScript |
|---|---|
| タイムスタンプ | 文字列 |
| 日付 | 文字列 |
| UUID | 文字列 |
| Int64 | 文字列 |
| Double | 数値 |
| 浮動小数点数 | 数値 |
TanStack を使用して React と Angular の SDK を生成する
Firebase SQL Connect は、パートナーの Invertase が提供するライブラリ TanStack Query Firebase を使用して、React と Angular のフックを含む生成済み SDK を提供します。
このライブラリは、アプリケーションで Firebase を使用した非同期タスクの処理を大幅に簡素化する一連のフックを提供します。
TanStack には、クライアントサイド キャッシュ保存とリアルタイム サブスクリプションの独自の実装が付属しています。これは SQL Connect の組み込みのリアルタイム サポートと連携できますが、多少の困難が伴います。TanStack ベースのバインディングまたは SQL Connect の組み込みのリアルタイム サポートのいずれかを使用することをおすすめします。両方を使用することはおすすめしません。
SQL Connect 独自のリアルタイム実装には、TanStack バインディングよりも優れた点がいくつかあります。
- 正規化されたキャッシュ保存: SQL Connect は正規化されたキャッシュ保存を実装します。これにより、クエリレベルのキャッシュ保存と比較して、データの整合性、メモリ、ネットワークの効率が向上します。正規化されたキャッシュ保存では、アプリの 1 つの領域でエンティティが更新されると、そのエンティティを使用する他の領域でも更新されます。
- リモート無効化: SQL Connect は、登録されているすべてのデバイスでキャッシュに保存されたエンティティをリモートで無効化できます。
アプリを初期化する
まず、他の Firebase ウェブアプリと同様に、標準の Firebase シーケンスを使用してアプリを初期化します。
initializeApp({...});
TanStack Query Firebase パッケージをインストールする
プロジェクトに TanStack Query のパッケージをインストールします。
React
npm i --save @tanstack/react-query @tanstack-query-firebase/react
npm i --save firebase@latest # Note: React has a peer dependency on ^11.3.0
Angular
ng add @angular/fire
React または Angular SDK を生成する
前述のとおり、標準のウェブ SDK と同様に、Firebase ツールはスキーマとオペレーションに基づいて SDK の自動生成を処理します。
プロジェクトに React または Angular を追加したばかりの場合は、firebase init dataconnect:sdk を再度実行して、生成された SDK を再構成し、追加のフレームワーク バインディングを含めます。
ライブラリをインポートする
React または Angular クライアント コードを初期化するには、一般的な SQL Connect インポート、一般的な TanStack インポート、JS および React 生成 SDK の特定のインポートの 4 つのインポート セットが必要です。
一般的なインポートに ConnectorConfig 型が含まれていることに注意してください。
React
// general imports
import { ConnectorConfig, DataConnect, getDataConnect, QueryRef, MutationRef, QueryPromise, MutationPromise } from 'firebase/data-connect';
// TanStack Query-related functions
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
// generated queries and mutations from SDK
import { ListMoviesResponse, connectorConfig } from '@dataconnect/generated';
// generated React hooks from SDK
import { useListAllMovies, useCreateMovie } from "@dataconnect/generated/react";
Angular
// general imports
import { ConnectorConfig, DataConnect, getDataConnect, QueryRef, MutationRef, QueryPromise, MutationPromise } from 'firebase/data-connect';
// TanStack Query-related functions
import { provideTanStackQuery, QueryClient } from "@tanstack/angular-query-experimental";
// generated queries and mutations from SDK
import { ListMoviesResponse, connectorConfig } from '@dataconnect/generated';
// generated React hooks from SDK
import { injectListAllMovies, injectCreateMovie } from "@dataconnect/generated/angular";
React または Angular クライアントでクエリとミューテーションを使用する
設定が完了したら、生成された SDK のメソッドを組み込むことができます。
次のスニペットでは、生成された SDK の React 用の use 接頭辞付きメソッド useListAllMovies と、Angular 用の inject 接頭辞付きメソッド injectListAllMovies に注目してください。
React
生成された SDK のこのようなオペレーション(クエリとミューテーションの両方)は、TanStackQuery バインディングを呼び出します。
- クエリは TanStack
useDataConnectQueryフックを呼び出して返します。 - ミューテーションは TanStack
useDataConnectMutationフックを呼び出して返します。
import { useListAllMovies } from '@dataconnect/generated/react';
function MyComponent() {
const { isLoading, data, error } = useListAllMovies();
if(isLoading) {
return <div>Loading...</div>
}
if(error) {
return <div> An Error Occurred: {error} </div>
}
}
// App.tsx
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import MyComponent from './my-component';
function App() {
const queryClient = new QueryClient();
return <QueryClientProvider client={queryClient}>
<MyComponent />
</QueryClientProvider>
}
Angular
import { injectAllMovies, connectorConfig } from '@dataconnect/generated/angular';
import { provideDataConnect, getDataConnect } from '@angular/fire/data-connect';
import { provideTanStackQuery, QueryClient } from "@tanstack/angular-query-experimental";
const queryClient = new QueryClient();
...
providers: [
...
provideTanStackQuery(queryClient),
provideDataConnect(() => {
const dc = getDataConnect(connectorConfig);
return dc;
})
]
React と Angular で自動再読み込みクエリを使用する
データが変更されたときに自動的に再読み込みされるようにクエリを構成できます。
React
export class MovieListComponent {
movies = useListAllMovies();
}
export class AddPostComponent {
const mutation = useCreateMovie({ invalidate: [listAllMoviesRef()] });
addMovie() {
// The following will automatically cause TanStack to reload its listAllMovies query
mutation.mutate({ title: 'The Matrix });
}
}
Angular
// class
export class MovieListComponent {
movies = injectListAllMovies();
}
// template
@if (movies.isPending()) {
Loading...
}
@if (movies.error()) {
An error has occurred: {{ movies.error() }}
}
@if (movies.data(); as data) {
@for (movie of data.movies; track movie.id) {
<mat-card appearance="outlined">
<mat-card-content>{{movie.description}}</mat-card-content>
</mat-card>
} @empty {
<h2>No items!</h2>
}
}
SQL Connect エミュレータに接続する
必要に応じて、次のように connectDataConnectEmulator を呼び出し、生成されたフックに SQL Connect インスタンスを渡すことで、エミュレータに接続できます。
React
import { getDataConnect, connectDataConnectEmulator } from 'firebase/data-connect';
import { connectorConfig } from '@dataconnect/generated';
import { useListAllMovies } from '@dataconnect/generated/react';
const dc = getDataConnect(connectorConfig);
connectDataConnectEmulator(dc, 'localhost', 9399);
class AppComponent() {
...
const { isLoading, data, error } = useListAllMovies(dc);
...
}
Angular
// app.config.ts
import { provideDataConnect } from '@angular/fire/data-connect';
import { getDataConnect, connectDataConnectEmulator } from 'firebase/data-connect';
provideDataConnect(() => {
const dc = getDataConnect(connectorConfig);
connectDataConnectEmulator(dc, 'localhost', 9399);
return dc;
}),
本番環境リソースに切り替えるには、エミュレータへの接続に関する行をコメントアウトします。
プロトタイピング中に 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