Web SDK
Consult this file when writing client-side web code (TypeScript/JavaScript) that interacts with the SQL Connect backend.
Best Practices for Agents
- Understand Operation Storage: SQL Connect queries and mutations are stored on the server like Cloud Functions. Whenever you update operations, you must regenerate the SDK and redeploy services that use it to avoid breaking clients.
- Resilient Enum Handling: JavaScript/TypeScript does not enforce exhaustive
checks on enums. Always add a
defaultbranch toswitchstatements or anelsebranch to handle unknown values gracefully when schemas evolve. - TanStack Query vs. Native: You can generate hooks for React/Angular using TanStack Query. Choose either TanStack or SQL Connect's built-in real-time and caching support, but do not use both in the same project. SQL Connect offers normalized caching and remote invalidation.
- Emulator Connection:
connectDataConnectEmulatoris only required if connecting to the emulator. Otherwise, the generated SDK auto-creates the instance.
Installation
npm install firebase
firebase init dataconnect:sdkInitialization
import { connectDataConnectEmulator, getDataConnect } from 'firebase/data-connect';
import { connectorConfig } from '@dataconnect/generated';
const dataConnect = getDataConnect(connectorConfig);
// Configure the SDK to use local emulator
connectDataConnectEmulator(dataConnect, 'localhost', 9399);Calling Operations
Using executeQuery (Preferred for clarity)
import { executeQuery } from 'firebase/data-connect';
import { listMoviesRef } from '@dataconnect/generated';
const ref = listMoviesRef();
const { data } = await executeQuery(ref);
console.log(data.movies);Using Action Shortcuts
import { listMovies } from '@dataconnect/generated';
listMovies().then(data => showInUI(data));Resilient Enum Handling
Use a default case or check against Object.values.
import { getOldestMovie } from '@dataconnect/generated';
const queryResult = await getOldestMovie();
if (queryResult.data) {
const oldestMovieAspectRatio = queryResult.data.originalAspectRatio;
switch (oldestMovieAspectRatio) {
case AspectRatio.ACADEMY:
case AspectRatio.WIDESCREEN:
console.log('Filmed in Academy or Widescreen!');
break;
default:
// The default case will catch FULLSCREEN, etc.
console.log('Not filmed in Academy or Widescreen.');
break;
}
}Client-Side Caching
Enable caching in connector.yaml:
generate:
javascriptSdk:
outputDir: ../web/
package: "@dataconnect/generated"
clientCache:
maxAge: 5s
storage: memory # Only memory is supported on WebUse policies in code:
await executeQuery(queryRef, { fetchPolicy: QueryFetchPolicy.CACHE_ONLY });
await executeQuery(queryRef, { fetchPolicy: QueryFetchPolicy.SERVER_ONLY });Subscriptions (Realtime)
Use subscribe() to receive live updates. It accepts either an observer object (SubscriptionOptions) or positional callbacks:
Note: When passing an observer object literal, the error callback property is named
onErr({ onNext, onErr, onComplete }). PassingonErrorin an object literal fails TypeScript compilation (TS2769) and is ignored at runtime. The nameonErroris only used as the parameter name in the positional callback overload (subscribe(ref, onNext, onError, onComplete)).
Web (Vanilla JS / TypeScript)
import { subscribe } from 'firebase/data-connect';
import { getMovieByIdRef } from '@dataconnect/generated';
const queryRef = getMovieByIdRef({ id: "<MOVIE_ID>" });
// Option 1: Observer object (recommended — uses `onErr`)
const unsubscribe = subscribe(queryRef, {
onNext: (result) => console.log("Updated result:", result),
onErr: (error) => console.error("Subscription error:", error)
});
// Option 2: Positional callbacks (`onNext`, `onError`, `onComplete`)
const unsubscribePositional = subscribe(
queryRef,
(result) => console.log("Updated result:", result),
(error) => console.error("Subscription error:", error)
);TanStack Query Support (React)
To use React hooks, re-run firebase init dataconnect:sdk after adding React.
Usage
import { useListAllMovies } from "@dataconnect/generated/react";
function MyComponent() {
const { isLoading, data, error } = useListAllMovies();
// handle loading, error, and data
}Data Type Mapping Reference
- GraphQL
Timestamp-> TypeScriptstring - GraphQL
Date-> TypeScriptstring - GraphQL
UUID-> TypeScriptstring - GraphQL
Int64-> TypeScriptstring - GraphQL
Double-> TypeScriptnumber - GraphQL
Float-> TypeScriptnumber