生成されたウェブ SDK を使用する

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

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

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

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

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

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

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

  1. ウェブアプリに Firebase を追加します。

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

  1. アプリのスキーマを開発します。
  2. JavaScript SDK を使用してクライアント コードを初期化します。
  3. SDK の生成を設定します。
    • SQL Connect VS Code 拡張機能の [Add SDK to app] ボタンを使用します。
    • JavaScript SDKconnector.yaml を更新します。
  4. JavaScript SDK を使用してライブラリと生成されたコードをインポートします。
  5. JavaScript SDK を使用して、クエリとミューテーションの呼び出しを実装します。
  6. JavaScript SDK を使用して SQL Connect エミュレータを設定し、テストします。

Firebase JavaScript SDK を使用してクライアント コードを実装する

このセクションでは、Firebase JavaScript SDK を使用してクライアントを実装する方法について説明します。

React または Angular を使用している場合は、代替の設定手順と、 フレームワーク用の SDKSQL Connect の生成に関する追加ドキュメントへのリンクをご覧ください

アプリを初期化する

まず、 標準の 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 は常に新しい値を取得することを意味します。キャッシュに保存された値は、executeQuery()CACHE_ONLY が指定され、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 数値
Float 数値

TanStack を使用して React および Angular SDK を生成する

Firebase SQL Connect には、Invertase のパートナーである TanStack Query Firebase から入手できるライブラリを使用して、React と Angular のフックを含む生成済み SDK が用意されています。

このライブラリには、アプリケーションで Firebase を使用した非同期タスクの処理を大幅に簡素化するフックのセットが用意されています。

TanStack には、クライアントサイド キャッシュ とリアルタイム サブスクリプションの独自の実装が用意されています。これは、 SQL Connect's の組み込みのリアルタイム サポートと連携して動作しますが、多少の 困難が伴います。TanStack ベースのバインディングまたは SQL Connect's の組み込みのリアルタイム サポートのいずれかを使用することをおすすめします。両方 を使用することはおすすめしません。

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-prefixed メソッド useListAllMovies と、Angular 用の inject-prefixed メソッド injectListAllMovies に注目してください。

React

生成された SDK のこのようなオペレーション(クエリとミューテーションの両方)は、TanStackQuery バインディングを呼び出します。

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