Firebase Data Connect クライアント SDK を使用すると、Firebase アプリからサーバーサイドのクエリとミューテーションを直接呼び出すことができます。Data Connect サービスにデプロイするスキーマ、クエリ、ミューテーションを設計するのと並行して、カスタム クライアント SDK を生成します。次に、この SDK のメソッドをクライアント ロジックに統合します。
別の場所でも説明しましたが、Data Connect クエリとミューテーションはクライアント コードによって送信され、サーバーで実行されるわけではありません。代わりに、デプロイ時に Data Connect オペレーションは Cloud Functions のようにサーバーに保存されます。つまり、既存のユーザー(古いバージョンのアプリなど)を壊さないように、対応するクライアントサイドの変更をデプロイする必要があります。
そのため、Data Connect には、サーバーにデプロイされたスキーマ、クエリ、ミューテーションのプロトタイプを作成できるデベロッパー環境とツールが用意されています。また、プロトタイピング中にクライアントサイド SDK を自動的に生成します。
サービスアプリとクライアント アプリの更新を繰り返すと、サーバーサイドとクライアントサイドの両方の更新をデプロイできるようになります。
クライアント開発のワークフローとは何ですか?
スタートガイドに沿って、Data Connect の開発フロー全体について説明しました。このガイドでは、スキーマから Web SDK を生成し、クライアント クエリとミューテーションを操作する方法について詳しく説明します。
要約すると、生成された Web SDK をクライアント アプリで使用するには、次の前提条件の手順を行います。
- ウェブアプリに Firebase を追加します。
次に、以下のリソースをご覧ください。
- アプリのスキーマを開発します。
- JavaScript SDK、React ライブラリ、Angular ライブラリを使用して、クライアント コードを初期化します。
- React と Angular の場合は、Tanstack Query パッケージをインストールします。
SDK の生成を設定します。
- Data Connect VS Code 拡張機能の [Add SDK to app] ボタンを使用する
- JavaScript SDK、React、Angular の
connector.yaml
を更新します。
JavaScript SDK、React、Angular を使用して、ライブラリと生成されたコードをインポートします。
JavaScript SDK、React、または Angular を使用して、クエリとミューテーションの呼び出しを実装します。
JavaScript SDK、React、Angular を使用して Data Connect エミュレータを設定し、テストします。
Firebase JavaScript SDK を使用してクライアント コードを実装する
このセクションでは、Firebase JavaScript SDK を使用してクライアントを実装する方法について説明します。
React または Angular を使用している場合は、フレームワーク用の Data Connect SDK の生成に関する代替のセットアップ手順と追加のドキュメントへのリンクをご覧ください。
アプリを初期化する
まず、標準の Firebase シーケンスを使用してアプリを初期化します。
initializeApp({...});
JavaScript SDK を生成する
ほとんどの Firebase プロジェクトと同様に、Firebase Data Connect クライアント コードの作業はローカル プロジェクト ディレクトリで行われます。Data Connect VS Code 拡張機能と Firebase CLI は、クライアント コードの生成と管理に不可欠なローカルツールです。
SDK 生成オプションは、プロジェクトの初期化時に生成された dataconnect.yaml
ファイルの複数のエントリにキー設定されています。
SDK の生成を初期化する
connector.yaml
に、outputDir
、package
、(ウェブ SDK の場合)packageJsonDir
を追加します。generate:
javascriptSdk:
outputDir: "../movies-generated"
package: "@movie-app/movies"
packageJsonDir: "../../"
outputDir
は、生成された SDK の出力先を指定します。
package
にはパッケージ名を指定します。
packageJsonDir
は、パッケージのインストール先を指定します。
この場合、このピア依存関係が満たされるように firebase@latest
をインストールします。
JavaScript SDK を初期化する
Data Connect の設定に使用した情報(Firebase コンソールの [Data Connect] タブで確認可能)を使用して、Data Connect インスタンスを初期化します。
ConnectorConfig オブジェクト
SDK にはコネクタ構成オブジェクトが必要です。
このオブジェクトは、dataconnect.yaml
の serviceId
と location
、connector.yaml
の connectorId
から自動的に生成されます。
ライブラリをインポートする
クライアント コードを初期化するには、一般的な Data 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 '@myorg/myconnector';
JavaScript SDK からクエリを使用する
生成されたコードには、事前定義されたクエリ参照がすでに含まれています。必要なのは、それらをインポートして実行するだけです。
import { executeQuery } from 'firebase/data-connect';
import { listMoviesRef } from '@movie-app/movies';
const ref = listMoviesRef();
const { data } = await executeQuery(ref);
console.log(data.movies);
SDK のクエリ メソッドを呼び出す
これらのアクション ショートカット関数を使用した例を次に示します。
import { listMovies } from '@movie-app/movies';
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);
}
変更を購読する
変更をサブスクライブできます(クエリを実行するたびに更新されます)。
const listRef = listAllMoviesRef();
// subscribe will immediately invoke the query if no execute was called on it previously.
subscribe(listRef, ({ data }) => {
updateUIWithMovies(data.movies);
});
await createMovie({ title: 'Empire Strikes Back', releaseYear: 1980, genre: "Sci-Fi", rating: 5 });\
await listMovies(); // will update the subscription above`
列挙型フィールドの変更を処理する
アプリのスキーマには列挙型を含めることができ、GraphQL クエリでアクセスできます。
アプリの設計が変更されたら、サポートされている新しい列挙値を追加できます。たとえば、アプリのライフサイクルの後半で、AspectRatio
列挙型に FULLSCREEN 値を追加するとします。
Data 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 '@movie-app/movies';
const { data } = await executeMutation(createMovieRef({ movie: 'Empire Strikes Back' }));
Data Connect エミュレータに接続する
必要に応じて、次のように connectDataConnectEmulator
を呼び出して Data Connect インスタンスを渡すことで、エミュレータに接続できます。
import { connectDataConnectEmulator } from 'firebase/data-connect';
import { connectorConfig } from '@myorg/myconnector'; // Replace with your package name
const dataConnect = getDataConnect(connectorConfig);
connectDataConnectEmulator(dataConnect, 'localhost', 9399);`
// Make calls from your app
本番環境リソースに切り替えるには、エミュレータへの接続に関する行をコメントアウトします。
React と Angular のクライアント コードを実装する
Firebase Data Connect は、パートナーの Invertase が提供するライブラリ TanStack Query Firebase を使用して、React と Angular のフックを含む生成済み SDK を提供します。
このライブラリは、アプリケーションで Firebase を使用した非同期タスクの処理を大幅に簡素化する一連のフックを提供します。
アプリを初期化する
まず、他の 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 SDK を生成するには、connector.yaml
構成ファイルに react
キーを追加します。
React
generate:
javascriptSdk:
react: true
outputDir: "../movies-generated"
package: "@movie-app/movies"
packageJsonDir: "../../"
Angular
generate:
javascriptSdk:
angular: true
outputDir: "../movies-generated"
package: "@movie-app/movies"
packageJsonDir: "../../"
ライブラリをインポートする
React または Angular クライアント コードを初期化するには、4 つのインポート セットが必要です。一般的な Data Connect インポート、一般的な TanStack インポート、JS と React で生成された SDK の特定のインポートです。
一般的なインポートに 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 '@myorg/myconnector';
// generated React hooks from SDK
import { useListAllMovies, useCreateMovie } from "@myorg/connector/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 '@myorg/myconnector';
// generated React hooks from SDK
import { injectListAllMovies, injectCreateMovie } from "@myorg/connector/angular";
React または Angular クライアントでクエリとミューテーションを使用する
設定が完了したら、生成された SDK のメソッドを組み込むことができます。
次のスニペットでは、生成された SDK の React 用の use
接頭辞付きメソッド useListAllMovies
と Angular 用の inject
接頭辞付きメソッド injectListAllMovies
に注目してください。
React
生成された SDK のこのようなオペレーション(クエリとミューテーションの両方)は、TanStackQuery バインディングを呼び出します。
- クエリは TanStack
useDataConnectQuery
フックを呼び出して返します。 - ミューテーションは TanStack
useDataConnectMutation
フックを呼び出して返します。
import { useListAllMovies } from '@movies-app/movies/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 '@movies-app/movies/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>
}
}
Data Connect エミュレータに接続する
必要に応じて、次のように connectDataConnectEmulator
を呼び出し、生成されたフックに Data Connect インスタンスを渡すことで、エミュレータに接続できます。
React
import { getDataConnect, connectDataConnectEmulator } from 'firebase/data-connect';
import { connectorConfig } from '@movies-app/movies';
import { useListAllMovies } from '@movies-app/movies/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 のデータ型
Data Connect サーバーは、一般的な GraphQL データ型を表します。これらは SDK で次のように表されます。
データ接続タイプ | TypeScript |
---|---|
タイムスタンプ | 文字列 |
日付 | 文字列 |
UUID | 文字列 |
Int64 | 文字列 |
Double | 数値 |
浮動小数点数 | 数値 |
SDK の生成に関する特別な考慮事項
node_modules
を基準としたパスを構成する
JavaScript SDK の場合、Data Connect は npm link
を使用して SDK をインストールするため、生成された SDK は node_modules
パスと同じレベルのディレクトリ、または node_modules
にアクセスできる子ディレクトリに出力する必要があります。
つまり、生成された SDK が正しく動作するには、firebase
ノード モジュールにアクセスできる必要があります。
たとえば、node_modules
が my-app/
にある場合、js-email-generated
が親の node_modules
フォルダからインポートできるように、出力ディレクトリは my-app/js-email-generated
にする必要があります。
my-app/
dataconnect/
connector/
connector.yaml
node_modules/
firebase/
js-email-generated/
// connector.yaml
connectorId: "my-connector"
generate:
javascriptSdk:
outputDir: "../../js-email-generated"
package: "@myapp/my-connector"
または、モジュールがルートでホストされている monorepo がある場合は、monorepo の任意のフォルダに出力ディレクトリを配置できます。
my-monorepo/
dataconnect/
connector/
connector.yaml
node_modules/
firebase/
my-app/
js-email-generated/
package.json
// connector.yaml
connectorId: "my-connector"
generate:
javascriptSdk:
outputDir: "../../my-app/js-email-generated" # You can also output to ../../js-email-generated
プロトタイピング中に SDK を更新する
Data Connect VS Code 拡張機能とその Data Connect エミュレータを使用してインタラクティブにプロトタイピングを行う場合、スキーマ、クエリ、ミューテーションを定義する .gql
ファイルを変更すると、SDK ソースファイルが自動的に生成され、更新されます。これは、ホット(再)読み込みワークフローで役立つ機能です。
.gql
の更新を監視し、SDK ソースを自動的に更新することもできます。
または、CLI を使用して、.gql ファイルが変更されるたびに SDK を再生成することもできます。
firebase dataconnect:sdk:generate --watch
統合用と本番環境リリース用の SDK を生成する
CI テスト用に送信するプロジェクト ソースの準備など、一部のシナリオでは、バッチ更新用に Firebase CLI を呼び出すことができます。
このような場合は、firebase dataconnect:sdk:generate
を使用します。