使用生成的 Web SDK

Firebase Data Connect 客户端 SDK,您可以直接从 Firebase 应用调用服务器端查询和 突变。在设计要部署到您的 Data Connect 服务的架构、查询和突变时,您可以并行生成自定义客户端 SDK。然后,您可以将此 SDK 中的方法集成到客户端逻辑中。

正如我们在其他地方提到的,请务必注意,Data Connect 查询和突变不是由客户端代码提交的,而是在 服务器上执行的。相反,部署后,Data Connect 操作会像 Cloud Functions 一样存储在 服务器上。这意味着,您需要部署相应的客户端更改,以避免影响现有用户(例如,在旧版应用中)。

因此,Data Connect 为您提供了一个开发者环境和 工具,让您可以对服务器部署的架构、查询和突变进行原型设计。 它还会在您进行原型设计时自动生成客户端 SDK。

当您迭代更新服务和客户端应用时,服务器端和客户端更新都可以部署了。

什么是客户端开发工作流?

如果您已完成使用入门,则应该已经 了解 Data Connect 的整体开发流程。在本指南中,您将找到有关从架构生成 Web SDK 以及使用客户端查询和突变的更详细信息。

总而言之,如需在客户端应用中使用生成的 Web SDK,您需要按照以下前提条件步骤操作:

  1. 将 Firebase 添加到您的 Web 应用。

然后:

  1. 开发应用架构。
  2. 使用 JavaScript SDKReactAngular 库初始化客户端代码。
  3. 对于 React 和 Angular,请安装 Tanstack Query 软件包
  4. 设置 SDK 生成:

    • 使用 Data Connect VS Code 扩展程序中的将 SDK 添加到应用 按钮
    • 通过为 JavaScript SDKReactAngular 更新您的 connector.yaml
  5. 使用 JavaScript SDKReactAngular 导入库和生成的代码。

  6. 使用 JavaScript SDKReactAngular 实现对查询和突变的调用。

  7. 通过使用Data Connect模拟器设置 JavaScript SDK,或ReactAngular进行测试。

使用 Firebase JavaScript SDK 实现客户端代码

本部分介绍了如何使用 Firebase JavaScript SDK 实现客户端。

如果您使用的是 React 或 Angular,请参阅有关为框架生成 SDKData Connect 的替代设置说明和指向 其他文档的链接

初始化您的应用

首先,使用 标准 Firebase 序列初始化您的应用。

initializeApp({...});

安装生成的 JavaScript SDK

使用 Firebase CLI 在应用中设置 Data Connect 生成的 SDK。 init 命令应检测当前文件夹中的所有应用,并自动安装生成的 SDK。

firebase init dataconnect:sdk

将应用连接到 Data 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

如果您安装了 Data Connect VS Code 扩展程序,它将始终使生成的 SDK 保持最新状态。

如果您不使用 Data Connect VS Code 扩展程序,则可以使用 Firebase CLI 使生成的 SDK 保持最新状态。

firebase dataconnect:sdk:generate --watch

在 build 流水线中生成 SDK

您可以使用 Firebase CLI 在 CI/CD build 流程中生成 Data Connect SDK。

firebase dataconnect:sdk:generate

导入库

初始化客户端代码需要两组导入:常规 Data Connect 导入和特定的生成的 SDK 导入。

请注意常规导入中包含的 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);
}

订阅更改

您可以订阅更改(这会在您每次执行查询时更新)。

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。

但是,在您发布客户端的更新版本之前,较旧的已部署客户端可能会中断。

弹性实现示例

始终向枚举值的 default 语句添加 switch 分支,或 向与枚举值进行比较的 else 块添加 if/else if 分支。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' }));

连接到 Data Connect 模拟器

(可选)您可以通过调用 connectDataConnectEmulator,然后传入Data 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

如需切换到生产环境资源,请注释掉用于连接到模拟器的行。

为 React 和 Angular 实现客户端代码

Firebase Data Connect 提供了一个生成的 SDK,其中包含 React 和 Angular 的钩子,这些钩子使用来自我们的合作伙伴 Invertase, TanStack Query Firebase 的库。

此库提供了一组钩子,可大大简化在应用中使用 Firebase 处理异步任务的过程。

初始化您的应用

首先,与任何 Firebase Web 应用一样,使用 标准 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

与标准 Web SDK 一样(如前所述),Firebase 工具会根据您的架构和操作自动生成 SDK。

如果您刚刚向项目中添加了 React 或 Angular,请重新运行 firebase init dataconnect:sdk 以重新配置生成的 SDK,使其包含额外的框架绑定。

导入库

初始化 React 或 Angular 客户端代码需要四组导入:常规 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 '@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 中的方法。

在以下代码段中,请注意 use- 前缀方法 useListAllMovies(适用于 React)和 inject- 前缀方法 injectListAllMovies(适用于 Angular),它们都来自生成的 SDK。

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>
    }
}

连接到 Data Connect 模拟器

(可选)您可以通过调用 connectDataConnectEmulator,然后将 Data 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 中的数据类型

Data Connect 服务器表示常见的 GraphQL 数据类型。这些类型在 SDK 中表示如下。

Data Connect 类型 TypeScript
时间戳 字符串
日期 字符串
UUID 字符串
Int64 字符串
双精度型 数字
浮点数 数字

在原型设计期间更新 SDK

如果您安装了 Data Connect VS Code 扩展程序,它将始终使生成的 SDK 保持最新状态。

如果您不使用 Data Connect VS Code 扩展程序,则可以使用 Firebase CLI 使生成的 SDK 保持最新状态。

firebase dataconnect:sdk:generate --watch

在 build 流水线中生成 SDK

您可以使用 Firebase CLI 在 CI/CD build 流程中生成 Data Connect SDK。

firebase dataconnect:sdk:generate