Usa SDKs web generados

Los SDKs cliente de Firebase SQL Connect te permiten llamar a tus consultas y mutaciones del servidor directamente desde una app de Firebase. Generas un SDK cliente personalizado en paralelo a medida que diseñas los esquemas, las consultas y las mutaciones que implementas en tu servicio de SQL Connect. Luego, integras métodos de este SDK en la lógica de tu cliente.

Como mencionamos en otro lugar, es importante tener en cuenta que el código del cliente no envía consultas ni mutaciones, y que estas no se ejecutan en el servidor.SQL Connect En cambio, cuando se implementan, las operaciones de SQL Connect se almacenan en el servidor, como Cloud Functions. Esto significa que debes implementar los cambios correspondientes del cliente para evitar que se interrumpa la experiencia de los usuarios existentes (por ejemplo, en versiones anteriores de la app).

Por eso, SQL Connect te proporciona un entorno de desarrollo y herramientas que te permiten crear prototipos de tus esquemas, consultas y mutaciones implementados en el servidor. También genera automáticamente SDKs del cliente mientras creas prototipos.

Cuando hayas iterado las actualizaciones de tus apps de servicio y cliente, las actualizaciones del servidor y del cliente estarán listas para implementarse.

¿Cuál es el flujo de trabajo de desarrollo de clientes?

Si seguiste la sección Comienza ahora, conociste el flujo de desarrollo general de SQL Connect. En esta guía, encontrarás información más detallada para generar SDKs web a partir de tu esquema y trabajar con consultas y mutaciones del cliente.

En resumen, para usar los SDK web generados en tus apps cliente, deberás seguir estos pasos previos:

  1. Agrega Firebase a tu app web.

Luego, haz lo siguiente:

  1. Desarrolla el esquema de tu app.
  2. Inicializa tu código cliente con el SDK de JavaScript.
  3. Configura la generación del SDK:
    • Con el botón Add SDK to app en la extensión de SQL Connect para VS Code
    • Actualiza tu connector.yaml para el SDK de JavaScript.
  4. Importa bibliotecas y código generado con el SDK de JavaScript.
  5. Implementa llamadas a consultas y mutaciones con el SDK de JavaScript.
  6. Configura el emulador SQL Connect con el SDK de JavaScript para realizar pruebas.

Implementa código cliente con el SDK de Firebase JavaScript

En esta sección, se explica cómo puedes implementar clientes con el SDK de Firebase JavaScript.

Si usas React o Angular, consulta las instrucciones de configuración alternativas y los vínculos a documentación adicional sobre la generación de SDKs de SQL Connect para frameworks.

Inicializa tu app

Primero, inicializa tu app con la secuencia estándar de Firebase.

initializeApp({...});

Instala el SDK de JavaScript generado

Usa la CLI de Firebase para configurar los SDKs generados por SQL Connect en tus apps. El comando init debería detectar todas las apps en la carpeta actual y, luego, instalar los SDKs generados automáticamente.

firebase init dataconnect:sdk

Conecta tu app al servicio 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);

Actualiza los SDKs durante la creación de prototipos

Si tienes instalada la extensión SQL Connect de VS Code, siempre mantendrá actualizados los SDKs generados.

Si no usas la extensión SQL Connect de VS Code, puedes usar Firebase CLI para mantener actualizados los SDKs generados.

firebase dataconnect:sdk:generate --watch

Genera SDKs en canalizaciones de compilación

Puedes usar Firebase CLI para generar SDKs de SQL Connect en los procesos de compilación de CI/CD.

firebase dataconnect:sdk:generate

Importa las bibliotecas

Se necesitan dos conjuntos de importaciones para inicializar el código del cliente: importaciones generales de SQL Connect e importaciones específicas del SDK generado.

Observa el objeto ConnectorConfig incluido en las importaciones generales.

// 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';

Usa consultas desde el SDK de JavaScript

El código generado ya incluirá referencias de consulta predefinidas. Lo único que debes hacer es importarlos y llamar a execute en ellos.

import { executeQuery } from 'firebase/data-connect';
import { listMoviesRef } from '@dataconnect/generated';

const ref = listMoviesRef();
const { data } = await executeQuery(ref);
console.log(data.movies);

Llama a los métodos de consulta del SDK

A continuación, se muestra un ejemplo en el que se usan estas funciones de acceso directo a acciones:

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

Suscríbete a los cambios

Consulta Cómo obtener actualizaciones en tiempo real de SQL Connect.

Cómo controlar los cambios en los campos de enumeración

El esquema de una app puede contener enumeraciones, a las que se puede acceder con tus consultas de GraphQL.

A medida que cambia el diseño de una app, es posible que agregues nuevos valores admitidos de enumeración. Por ejemplo, imagina que, más adelante en el ciclo de vida de tu aplicación, decides agregar un valor FULLSCREEN al enum AspectRatio.

En el flujo de trabajo de SQL Connect, puedes usar herramientas de desarrollo locales para actualizar tus consultas y SDKs.

Sin embargo, antes de lanzar una versión actualizada de tus clientes, es posible que los clientes implementados más antiguos dejen de funcionar.

Ejemplo de implementación resistente

Siempre agrega una rama default a una sentencia switch sobre los valores de la enumeración o una rama else a un bloque if/else if que se compare con los valores de la enumeración. El lenguaje JavaScript/TypeScript no aplica esta regla, pero es la forma de hacer que el código del cliente sea sólido en caso de que se agreguen nuevos valores de enumeración.

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!");
}

Usa mutaciones del SDK de JavaScript

Se puede acceder a las mutaciones de la misma manera que a las consultas.

import { executeMutation } from 'firebase/data-connect';
import { createMovieRef } from '@dataconnect/generated';

const { data } = await executeMutation(createMovieRef({ movie: 'Empire Strikes Back' }));

Conéctate al emulador de SQL Connect

De manera opcional, puedes conectarte al emulador llamando a connectDataConnectEmulator y, luego, pasando la instancia de SQL Connect, de la siguiente manera:

import { connectDataConnectEmulator } from 'firebase/data-connect';
import { connectorConfig } from '@dataconnect/generated';

const dataConnect = getDataConnect(connectorConfig);
connectDataConnectEmulator(dataConnect, 'localhost', 9399);`

// Make calls from your app

Para cambiar a los recursos de producción, comenta las líneas para conectarte al emulador.

Habilita el almacenamiento en caché del cliente

SQL Connect tiene una función de almacenamiento en caché opcional del cliente, que puedes habilitar editando el archivo connector.yaml. Cuando esta función está habilitada, los SDKs de cliente generados almacenan en caché de forma local las respuestas a las consultas, lo que puede reducir la cantidad de solicitudes de bases de datos que realiza tu app y permite que las partes de tu app que dependen de la base de datos funcionen cuando se interrumpe la disponibilidad de la red.

Para habilitar el almacenamiento en caché del cliente, agrega una configuración de almacenamiento en caché del cliente a la configuración del conector:

generate:
  javascriptSdk:
    outputDir: ../web/
    package: "@dataconnect/generated"
    clientCache:
      maxAge: 5s
      storage: memory

Esta configuración tiene dos parámetros, ambos opcionales:

  • maxAge: Es la antigüedad máxima que puede tener una respuesta almacenada en caché antes de que el SDK del cliente recupere valores nuevos. Ejemplos: "0", "30s", "1h30m".

    El valor predeterminado de maxAge es 0, lo que significa que las respuestas se almacenan en caché, pero el SDK del cliente siempre recuperará valores nuevos. Los valores almacenados en caché solo se usarán cuando CACHE_ONLY se especifique como executeQuery() y el resultado inicial se devuelva desde subscribe().

  • storage: El SDK cliente se puede configurar para almacenar en caché las respuestas en el almacenamiento de persistent o en memory. Los resultados almacenados en caché en el almacenamiento de persistent persistirán entre los reinicios de la app. En los SDKs web, solo se admite el almacenamiento de memory.

Después de actualizar la configuración de almacenamiento en caché del conector, vuelve a generar los SDKs del cliente y a compilar la app. Una vez que lo hagas, executeQuery() y subscribe() almacenarán en caché las respuestas y usarán los valores almacenados en caché según la política que configuraste. Por lo general, esto sucede automáticamente, sin que debas realizar ningún paso adicional. Sin embargo, ten en cuenta lo siguiente:

  • El comportamiento predeterminado de executeQuery() es el que se describió anteriormente: si se almacena en caché un resultado para una búsqueda y el valor almacenado en caché no es más antiguo que executeQuery(), se usa el valor almacenado en caché.maxAge Este comportamiento predeterminado se denomina política de PREFER_CACHE.

    También puedes especificar para las invocaciones individuales de executeQuery() que solo se publiquen valores almacenados en caché (CACHE_ONLY) o que se recuperen de forma incondicional valores nuevos del servidor (SERVER_ONLY).

    await executeQuery(queryRef, QueryFetchPolicy.CACHE_ONLY);
    
    await executeQuery(queryRef, QueryFetchPolicy.SERVER_ONLY);
    
  • Cuando llamas a subscribe(), siempre se muestra de inmediato el contenido almacenado en caché, si existe, independientemente de la configuración de maxAge. Las llamadas posteriores a executeQuery() notificarán a los objetos de escucha según el maxAge configurado.

Tipos de datos en el SDK

El servidor SQL Connect representa los tipos de datos comunes de GraphQL. Estos se representan en el SDK de la siguiente manera.

Tipo SQL Connect TypeScript
Marca de tiempo string
Fecha string
UUID string
Int64 string
Doble Número
Número de punto flotante Número

Genera SDKs de React y Angular con TanStack

Firebase SQL Connect proporciona un SDK generado con hooks para React y Angular que usan bibliotecas disponibles de nuestros socios en Invertase, TanStack Query Firebase.

Esta biblioteca proporciona un conjunto de hooks que facilitan en gran medida el manejo de tareas asíncronas con Firebase en tus aplicaciones.

TanStack incluye su propia implementación de almacenamiento en caché del cliente y suscripciones en tiempo real, que pueden funcionar junto con la compatibilidad integrada en tiempo real de SQL Connect, pero solo con cierta dificultad. Te recomendamos que uses las vinculaciones basadas en TanStack o la compatibilidad integrada en tiempo real de SQL Connect, pero no ambas.

Ten en cuenta que la implementación en tiempo real propia de SQL Connect tiene algunas ventajas sobre las vinculaciones de TanStack:

  • Almacenamiento en caché normalizado: SQL Connect implementa el almacenamiento en caché normalizado, que mejora la coherencia de los datos, así como la eficiencia de la memoria y la red en comparación con el almacenamiento en caché a nivel de la consulta. Con el almacenamiento en caché normalizado, si una entidad se actualiza en un área de tu app, también se actualizará en otras áreas que usen esa entidad.
  • Invalidación remota: SQL Connect puede invalidar de forma remota las entidades almacenadas en caché en todos los dispositivos suscritos.

Inicializa tu app

Primero, como con cualquier app web de Firebase, inicializa tu app con la secuencia estándar de Firebase.

initializeApp({...});

Instala los paquetes de TanStack Query Firebase

Instala los paquetes para TanStack Query en tu proyecto.

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

Genera tu SDK de React o Angular

Al igual que con el SDK web estándar, como se describió anteriormente, las herramientas de Firebase controlan la generación automática de SDKs según tu esquema y tus operaciones.

Si acabas de agregar React o Angular a tu proyecto, vuelve a ejecutar firebase init dataconnect:sdk para volver a configurar los SDKs generados y que incluyan las vinculaciones adicionales del framework.

Importa las bibliotecas

Hay cuatro conjuntos de importaciones necesarios para inicializar el código del cliente de React o Angular: importaciones generales de SQL Connect, importaciones generales de TanStack y las importaciones específicas para tus SDKs generados en JS y React.

Observa el tipo ConnectorConfig incluido en las importaciones generales.

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";

Usa consultas y mutaciones en tu cliente de React o Angular

Una vez que se complete la configuración, podrás incorporar métodos del SDK generado.

En el siguiente fragmento, observa el método useListAllMovies con el prefijo use para React y el método injectListAllMovies con el prefijo inject para Angular, ambos del SDK generado.

React

Todas las operaciones de este tipo en el SDK generado, tanto las consultas como las mutaciones, llaman a las vinculaciones de TanStack Query:

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;
  })
]

Usa consultas de recarga automática con React y Angular

Puedes configurar las consultas para que se vuelvan a cargar automáticamente cuando cambien los datos.

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

Conéctate al emulador de SQL Connect

De manera opcional, puedes conectarte al emulador llamando a connectDataConnectEmulator y, luego, pasando la instancia de SQL Connect a tu hook generado, de la siguiente manera:

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;
}),

Para cambiar a los recursos de producción, comenta las líneas para conectarte al emulador.

Actualiza los SDKs durante la creación de prototipos

Si tienes instalada la extensión SQL Connect de VS Code, siempre mantendrá actualizados los SDKs generados.

Si no usas la extensión SQL Connect de VS Code, puedes usar Firebase CLI para mantener actualizados los SDKs generados.

firebase dataconnect:sdk:generate --watch

Genera SDKs en canalizaciones de compilación

Puedes usar Firebase CLI para generar SDKs de SQL Connect en los procesos de compilación de CI/CD.

firebase dataconnect:sdk:generate