← Files FirebaseARCHIVED FILE

reference/sdk_web.md

4.78 KB · Nov 9, 2026 · 00:15 UTC

↓ Download file

See the change to this file →

# 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 `default` branch to `switch` statements or an
  `else` branch 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**: `connectDataConnectEmulator` is only required if
  connecting to the emulator. Otherwise, the generated SDK auto-creates the
  instance.

### Installation

```bash
npm install firebase
firebase init dataconnect:sdk
```

### Initialization

```typescript
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)

```typescript
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

```typescript
import { listMovies } from '@dataconnect/generated';

listMovies().then(data => showInUI(data));
```

### Resilient Enum Handling

Use a `default` case or check against `Object.values`.

```typescript
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`:

```yaml
generate:
  javascriptSdk:
    outputDir: ../web/
    package: "@dataconnect/generated"
    clientCache:
      maxAge: 5s
      storage: memory # Only memory is supported on Web
```

Use policies in code:

```typescript
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 }`). Passing `onError` in
> an object literal fails TypeScript compilation (`TS2769`) and is ignored at
> runtime. The name `onError` is only used as the parameter name in the
> positional callback overload (`subscribe(ref, onNext, onError, onComplete)`).

#### Web (Vanilla JS / TypeScript)

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

```typescript
import { useListAllMovies } from "@dataconnect/generated/react";

function MyComponent() {
  const { isLoading, data, error } = useListAllMovies();
  // handle loading, error, and data
}
```

### Data Type Mapping Reference

- GraphQL `Timestamp` -> TypeScript `string`
- GraphQL `Date` -> TypeScript `string`
- GraphQL `UUID` -> TypeScript `string`
- GraphQL `Int64` -> TypeScript `string`
- GraphQL `Double` -> TypeScript `number`
- GraphQL `Float` -> TypeScript `number`

SHA-256: 7981747b0bd892cf3266bcb76b977c7af8258709092d1a15ab18c6668fbfca7e