Firebase SQL Connect 用戶端 SDK 可讓您直接從 Firebase 應用程式呼叫伺服器端查詢和變異。在設計要部署至 SQL Connect 服務的結構定義、查詢和變異時,您會同時產生自訂用戶端 SDK。接著,將這個 SDK 的方法整合至用戶端邏輯。
如先前所述,請務必注意,SQL Connect查詢和變動並非由用戶端程式碼提交,而是在伺服器上執行。相反地,部署時,SQL Connect 作業會儲存在伺服器上,例如 Cloud Functions。這表示您需要部署相應的用戶端變更,以免影響現有使用者 (例如使用舊版應用程式的使用者)。
因此,SQL Connect 提供開發環境和工具,讓您為伺服器部署的結構定義、查詢和變異建立原型。此外,在您設計原型時,系統也會自動產生用戶端 SDK。
反覆更新服務和用戶端應用程式後,伺服器端和用戶端更新都已準備就緒,可以部署。
用戶端開發工作流程為何?
如果您已按照「入門指南」操作,應該已瞭解 SQL Connect 的整體開發流程。本指南將詳細說明如何從結構定義產生 Web 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 匯入項目。
請注意一般匯入項目中包含的 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
這項設定有兩個參數,皆為選用:
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 | 字串 |
| 雙人床 | 數字 |
| 浮點值 | 數字 |
使用 TanStack 產生 React 和 Angular SDK
Firebase SQL Connect 提供產生的 SDK,其中包含 React 和 Angular 的掛鉤,並使用合作夥伴 Invertase 提供的程式庫 TanStack Query Firebase。
這個程式庫提供一組掛鉤,可大幅簡化在應用程式中處理 Firebase 非同步工作的程序。
TanStack 內建用戶端快取和即時訂閱功能,可與 SQL Connect 的內建即時支援功能搭配使用,但難度較高。建議您使用以 TanStack 為基礎的繫結,或 SQL Connect 的內建即時支援,但不要同時使用兩者。
請注意,SQL Connect 自己的即時實作方式比 TanStack 繫結有一些優點:
- 正規化快取:SQL Connect 實作正規化快取,與查詢層級快取相比,可提升資料一致性,以及記憶體和網路效率。使用正規化快取時,如果應用程式某個區域中的實體更新,使用該實體的其他區域也會更新。
- 遠端撤銷:SQL Connect 可從遠端撤銷所有訂閱裝置上的快取實體。
初始化應用程式
首先,與任何 Firebase 網頁應用程式一樣,請使用標準 Firebase 序列初始化應用程式。
initializeApp({...});
安裝 TanStack Query Firebase 套件
在專案中安裝 TanStack Query 套件。
回應
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
如前文所述,Firebase 工具會根據您的結構定義和作業,自動產生 SDK,與標準網頁 SDK 相同。
如果您剛將 React 或 Angular 新增至專案,請重新執行 firebase init dataconnect:sdk,重新設定產生的 SDK,加入額外的框架繫結。
匯入程式庫
您需要匯入四組項目,才能初始化 React 或 Angular 用戶端程式碼:一般 SQL Connect 匯入項目、一般 TanStack 匯入項目,以及 JS 和 React 生成 SDK 的特定匯入項目。
請注意一般匯入項目中包含的 ConnectorConfig 類型。
回應
// 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 方法。
在下列程式碼片段中,請注意 React 的 use 前置字元方法 useListAllMovies 和 Angular 的 inject 前置字元方法 injectListAllMovies,兩者都來自產生的 SDK。
回應
產生的 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
您可以設定查詢,在資料變更時自動重新載入。
回應
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