Użyj wygenerowanych internetowych pakietów SDK

Firebase SQL Connect pakiety SDK klienta umożliwiają wywoływanie zapytań i mutacji po stronie serwera bezpośrednio z aplikacji w Firebase. Podczas projektowania schematów, zapytań i mutacji, które wdrażasz w usłudze SQL Connect równolegle generujesz niestandardowy pakiet SDK klienta. Następnie integrujesz metody z tego pakietu SDK z logiką klienta.

Jak już wspominaliśmy, ważne jest, aby pamiętać, że SQL Connect zapytania i mutacje nie są przesyłane przez kod klienta i wykonywane na serwerze. Zamiast tego po wdrożeniu operacje SQL Connect są przechowywane na serwerze, tak jak Cloud Functions. Oznacza to, że musisz wdrożyć odpowiednie zmiany po stronie klienta, aby nie zakłócić działania aplikacji u dotychczasowych użytkowników (np. w starszych wersjach aplikacji).

Dlatego SQL Connect udostępnia środowisko deweloperskie i narzędzia, które umożliwiają tworzenie prototypów schematów, zapytań i mutacji wdrożonych na serwerze. Podczas tworzenia prototypu automatycznie generuje też pakiety SDK po stronie klienta.

Gdy wprowadzisz aktualizacje usługi i aplikacji klienckich, aktualizacje po stronie serwera i klienta będą gotowe do wdrożenia.

Jak wygląda proces tworzenia klienta?

Jeśli wykonasz czynności opisane w przewodniku Pierwsze kroki, poznasz ogólny proces tworzenia aplikacji SQL Connect. W tym przewodniku znajdziesz bardziej szczegółowe informacje o generowaniu pakietów SDK do klienta internetowego na podstawie schematu oraz o pracy z zapytaniami i mutacjami klienta.

Podsumowując, aby używać wygenerowanych pakietów SDK do klienta internetowego w aplikacjach klienckich, musisz wykonać te czynności przygotowawcze:

  1. Dodaj Firebase do aplikacji internetowej.

Następnie:

  1. Opracuj schemat aplikacji.
  2. Zainicjuj kod klienta za pomocą pakietu JavaScript SDK.
  3. Skonfiguruj generowanie pakietu SDK:
    • Za pomocą przycisku Dodaj pakiet SDK do aplikacji w rozszerzeniu SQL Connect VS Code.
    • Aktualizując plik connector.yaml dla pakietu JavaScript SDK.
  4. Zaimportuj biblioteki i wygenerowany kod za pomocą pakietu JavaScript SDK.
  5. Zaimplementuj wywołania zapytań i mutacji za pomocą pakietu JavaScript SDK.
  6. Przeprowadź testy, konfigurując emulator SQL Connect za pomocą pakietu JavaScript SDK.

Implementowanie kodu klienta za pomocą pakietu Firebase JavaScript SDK

W tej sekcji dowiesz się, jak implementować klientów za pomocą pakietu Firebase JavaScript SDK.

Jeśli używasz Reacta lub Angulara, zapoznaj się z alternatywnymi instrukcjami konfiguracji i linkami do dodatkowej dokumentacji dotyczącej generowania SQL Connect pakietów SDK dla tych frameworków.

Inicjowanie aplikacji

Najpierw zainicjuj aplikację za pomocą standardowej sekwencji Firebase.

initializeApp({...});

Instalowanie wygenerowanego pakietu JavaScript SDK

Użyj interfejsu wiersza poleceń Firebase, aby skonfigurować wygenerowane pakiety SDK SQL Connect w swoich aplikacjach. Polecenie init powinno wykryć wszystkie aplikacje w bieżącym folderze i automatycznie zainstalować wygenerowane pakiety SDK.

firebase init dataconnect:sdk

Połącz aplikację z usługą 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);

Aktualizowanie pakietów SDK podczas tworzenia prototypu

Jeśli masz zainstalowane rozszerzenie SQL Connect VS Code, będzie ono zawsze aktualizować wygenerowane pakiety SDK.

Jeśli nie używasz rozszerzenia SQL Connect VS Code, możesz użyć wiersza poleceń Firebase, aby aktualizować wygenerowane pakiety SDK.

firebase dataconnect:sdk:generate --watch

Generowanie pakietów SDK w potokach kompilacji

Za pomocą wiersza poleceń Firebase możesz generować pakiety SDK SQL Connect w procesach kompilacji CI/CD.

firebase dataconnect:sdk:generate

Importowanie bibliotek

Aby zainicjować kod klienta, potrzebujesz 2 zestawów importów: ogólnych SQL Connect importów oraz konkretnych importów wygenerowanego pakietu SDK.

Zwróć uwagę na obiekt ConnectorConfig uwzględniony w importach ogólnych.

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

Używanie zapytań z pakietu JavaScript SDK

Wygenerowany kod będzie już zawierać predefiniowane odwołania do zapytań. Wystarczy je zaimportować i wywołać na nich polecenie execute.

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

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

Wywoływanie metod zapytań pakietu SDK

Oto przykład użycia tych funkcji skrótów do działań:

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

Subskrybowanie zmian

Zapoznaj się z artykułem Otrzymywanie aktualizacji w czasie rzeczywistym z SQL Connect.

Obsługiwanie zmian w polach wyliczeniowych

Schemat aplikacji może zawierać wyliczenia, do których można uzyskać dostęp za pomocą zapytań GraphQL.

W miarę zmian w projekcie aplikacji możesz dodawać nowe obsługiwane wartości wyliczeniowe. Wyobraź sobie na przykład, że w późniejszym etapie cyklu życia aplikacji zdecydujesz się dodać wartość FULLSCREEN do wyliczenia AspectRatio.

W procesie SQL Connect możesz używać lokalnych narzędzi deweloperskich do aktualizowania zapytań i pakietów SDK.

Zanim jednak opublikujesz zaktualizowaną wersję klientów, starsze wdrożone klienty mogą przestać działać.

Przykład implementacji odpornej na błędy

Zawsze dodawaj gałąź default do instrukcji switch dotyczącej wartości wyliczeniowych lub gałąź else do bloku if/else if porównującego z wartościami wyliczeniowymi. Nie jest to wymuszane przez język JavaScript/TypeScript, ale jest to sposób na zapewnienie niezawodności kodu klienta w przypadku dodania nowych wartości wyliczeniowych.

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

Używanie mutacji z pakietu JavaScript SDK

Mutacje są dostępne w taki sam sposób jak zapytania.

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

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

Łączenie się z emulatorem SQL Connect

Opcjonalnie możesz połączyć się z emulatorem, wywołując connectDataConnectEmulator a następnie przekazując instancję SQL Connect, tak jak poniżej:

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

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

// Make calls from your app

Aby przełączyć się na zasoby produkcyjne, zakomentuj wiersze służące do łączenia się z emulatorem.

Włączanie buforowania po stronie klienta

SQL Connect ma opcjonalną funkcję buforowania po stronie klienta, którą możesz włączyć, edytując plik connector.yaml. Gdy ta funkcja jest włączona, wygenerowane pakiety SDK klienta będą lokalnie buforować odpowiedzi na zapytania, co może zmniejszyć liczbę żądań bazy danych wysyłanych przez aplikację i umożliwić działanie części aplikacji zależnych od bazy danych w przypadku przerwy w dostępie do sieci.

Aby włączyć buforowanie po stronie klienta, dodaj konfigurację buforowania klienta do konfiguracji oprogramowania sprzęgającego:

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

Ta konfiguracja ma 2 parametry, które są opcjonalne:

  • maxAge: maksymalny wiek buforowanej odpowiedzi, po którym pakiet SDK klienta pobierze nowe wartości. Przykłady: „0”, „30s”, „1h30m”.

    Domyślna wartość maxAge to 0, co oznacza, że odpowiedzi są buforowane, ale pakiet SDK klienta zawsze będzie pobierać nowe wartości. Buforowane wartości będą używane tylko wtedy, gdy w przypadku executeQuery() określono CACHE_ONLY, a w przypadku subscribe() zwrócono wynik początkowy.

  • storage: pakiet SDK klienta można skonfigurować tak, aby buforował odpowiedzi w pamięci persistent lub memory. Wyniki buforowane w pamięci persistent będą zachowywane po ponownym uruchomieniu aplikacji. W pakietach SDK do klienta internetowego obsługiwana jest tylko pamięć memory.

Po zaktualizowaniu konfiguracji buforowania oprogramowania sprzęgającego wygeneruj ponownie pakiety SDK klienta i ponownie skompiluj aplikację. Gdy to zrobisz, executeQuery() i subscribe() będą buforować odpowiedzi i używać buforowanych wartości zgodnie ze skonfigurowanymi zasadami. Zwykle dzieje się to automatycznie, bez żadnych dodatkowych działań z Twojej strony. Pamiętaj jednak o tych kwestiach:

  • Domyślne działanie executeQuery() jest takie, jak opisano powyżej: jeśli wynik jest buforowany dla zapytania, a buforowana wartość nie jest starsza niż maxAge, użyj buforowanej wartości. To domyślne działanie jest nazywane zasadą PREFER_CACHE.

    Możesz też określić, że poszczególne wywołania executeQuery() mają zwracać tylko buforowane wartości (CACHE_ONLY) lub bezwarunkowo pobierać nowe wartości z serwera (SERVER_ONLY).

    await executeQuery(queryRef, QueryFetchPolicy.CACHE_ONLY);
    
    await executeQuery(queryRef, QueryFetchPolicy.SERVER_ONLY);
    
  • Gdy wywołasz subscribe(), zawsze natychmiast zwróci ono buforowaną treść, jeśli taka istnieje, niezależnie od ustawienia maxAge. Kolejne wywołania executeQuery() będą powiadamiać odbiorców zgodnie ze skonfigurowanym ustawieniem maxAge.

Typy danych w pakiecie SDK

Serwer SQL Connect reprezentuje typowe typy danych GraphQL. Są one reprezentowane w pakiecie SDK w ten sposób.

SQL Connect Typ TypeScript
Sygnatura czasowa ciąg znaków
Data ciąg znaków
UUID ciąg znaków
Int64 ciąg znaków
Liczba zmiennoprzecinkowa Liczba
Liczba zmiennoprzecinkowa Liczba

Generowanie pakietów SDK React i Angular za pomocą TanStack

Firebase SQL Connect udostępnia wygenerowany pakiet SDK z hookami dla Reacta i Angulara, korzystający z bibliotek dostępnych od naszych partnerów z Invertase, TanStack Query Firebase.

Ta biblioteka udostępnia zestaw hooków, które znacznie ułatwiają obsługę zadań asynchronicznych w Firebase w Twoich aplikacjach.

TanStack ma własną implementację buforowania po stronie klienta i subskrypcji w czasie rzeczywistym, która może współpracować z SQL Connect's wbudowaną obsługą w czasie rzeczywistym, ale tylko z pewnymi trudnościami. Zalecamy używanie albo powiązań opartych na TanStack, albo SQL Connect's wbudowanej obsługi w czasie rzeczywistym, ale nie obu naraz.

Pamiętaj, że własna implementacja w czasie rzeczywistym SQL Connect ma pewne zalety w porównaniu z powiązaniami TanStack:

  • Znormalizowane buforowanie: SQL Connect implementuje znormalizowane buforowanie, które poprawia spójność danych oraz wydajność pamięci i sieci w porównaniu z buforowaniem na poziomie zapytań. Dzięki znormalizowanemu buforowaniu, jeśli encja zostanie zaktualizowana w jednym obszarze aplikacji, zostanie też zaktualizowana w innych obszarach, które jej używają.
  • Zdalne unieważnianie: SQL Connect może zdalnie unieważniać buforowane   encje na wszystkich subskrybowanych urządzeniach.

Inicjowanie aplikacji

Najpierw, tak jak w przypadku każdej aplikacji internetowej Firebase, zainicjuj aplikację za pomocą standardowej sekwencji Firebase.

initializeApp({...});

Instalowanie pakietów TanStack Query Firebase

Zainstaluj pakiety TanStack Query w projekcie.

Dodaj reakcję

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

Generowanie pakietu SDK React lub Angular

Podobnie jak w przypadku standardowego pakietu SDK do klienta internetowego, narzędzia Firebase automatycznie generują pakiety SDK na podstawie schematu i operacji, jak opisano wcześniej.

Jeśli dopiero co dodajesz Reacta lub Angulara do projektu, ponownie uruchom polecenie firebase init dataconnect:sdk, aby ponownie skonfigurować wygenerowane pakiety SDK i uwzględnić dodatkowe powiązania platformy.

Importowanie bibliotek

Aby zainicjować kod klienta React lub Angular, potrzebujesz 4 zestawów importów: ogólnych importów SQL Connect, ogólnych importów TanStack oraz konkretnych importów wygenerowanych pakietów SDK JS i React.

Zwróć uwagę na typ ConnectorConfig uwzględniony w importach ogólnych.

Dodaj reakcję

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

Używanie zapytań i mutacji w kliencie React lub Angular

Po zakończeniu konfiguracji możesz uwzględnić metody z wygenerowanego pakietu SDK.

W poniższym fragmencie kodu zwróć uwagę na metodę z prefiksem useuseListAllMovies – w przypadku Reacta oraz metodę z prefiksem injectinjectListAllMovies – w przypadku Angulara. Obie te metody pochodzą z wygenerowanego pakietu SDK.

Dodaj reakcję

Wszystkie takie operacje w wygenerowanym pakiecie SDK, zarówno zapytania, jak i mutacje, wywołują powiązania 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;
  })
]

Używanie zapytań z automatycznym ponownym wczytywaniem w React i Angular

Możesz skonfigurować zapytania tak, aby automatycznie wczytywały się ponownie po zmianie danych.

Dodaj reakcję

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

Łączenie się z emulatorem SQL Connect

Opcjonalnie możesz połączyć się z emulatorem, wywołując connectDataConnectEmulator a następnie przekazując instancjęSQL Connect do wygenerowanego hooka, tak jak poniżej:

Dodaj reakcję

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

Aby przełączyć się na zasoby produkcyjne, zakomentuj wiersze służące do łączenia się z emulatorem.

Aktualizowanie pakietów SDK podczas tworzenia prototypu

Jeśli masz zainstalowane rozszerzenie SQL Connect VS Code, będzie ono zawsze aktualizować wygenerowane pakiety SDK.

Jeśli nie używasz rozszerzenia SQL Connect VS Code, możesz użyć wiersza poleceń Firebase, aby aktualizować wygenerowane pakiety SDK.

firebase dataconnect:sdk:generate --watch

Generowanie pakietów SDK w potokach kompilacji

Za pomocą wiersza poleceń Firebase możesz generować pakiety SDK SQL Connect w procesach kompilacji CI/CD.

firebase dataconnect:sdk:generate