Usa gli SDK Flutter generati

Firebase Data Connect SDK client ti consentono di chiamare le query e le mutazioni lato server direttamente da un'app Firebase. Generi un SDK client personalizzato in parallelo alla progettazione degli schemi, delle query e delle mutazioni di cui esegui il deployment nel tuo Data Connect servizio. Poi, integri i metodi di questo SDK nella logica del client.

Come abbiamo già detto, è importante notare che Data Connect query e mutazioni non vengono inviate dal codice client ed eseguite sul server. Quando viene eseguito il deployment, le operazioni Data Connect vengono archiviate su il server come Cloud Functions. Ciò significa che devi eseguire il deployment delle modifiche lato client corrispondenti per evitare di interrompere il funzionamento degli utenti esistenti (ad esempio, nelle versioni precedenti dell'app).

Per questo motivo, Data Connect ti fornisce un ambiente di sviluppo e strumenti che ti consentono di creare prototipi di schemi, query e mutazioni di cui hai eseguito il deployment sul server. Genera anche automaticamente gli SDK lato client durante la creazione del prototipo.

Dopo aver eseguito l'iterazione degli aggiornamenti del servizio e delle app client, gli aggiornamenti lato server e lato client sono pronti per il deployment.

Che cos'è il flusso di lavoro di sviluppo del client?

Se hai seguito la guida Introduzione, hai scoperto il flusso di sviluppo generale per Data Connect. In questa guida troverai informazioni più dettagliate sulla generazione di SDK Flutter dallo schema e sull'utilizzo di query e mutazioni client.

Per riassumere, per utilizzare gli SDK Flutter generati nelle app client, segui questi passaggi preliminari:

  1. Aggiungi Firebase alla tua app Flutter.
  2. Installa l'interfaccia a riga di comando flutterfire dart pub global activate flutterfire_cli.
  3. Esegui flutterfire configure.

Quindi:

  1. Sviluppa lo schema dell'app.
  2. Configura la generazione dell'SDK:

    • Con il pulsante Aggiungi SDK all'app nella nostra estensione Data Connect VS Code
    • Aggiornando il tuo connector.yaml.
  3. Inizializza il codice client e importa le librerie.

  4. Implementa le chiamate a query e mutazioni.

  5. Configura e utilizza l'emulatore Data Connect ed esegui l'iterazione.

Genera l'SDK Flutter

Utilizza l'interfaccia a riga di comando Firebase per configurare gli SDK generati da Data Connect nelle tue app. Il comando init dovrebbe rilevare tutte le app nella cartella corrente e installare automaticamente gli SDK generati.

firebase init dataconnect:sdk

Aggiorna gli SDK durante la creazione del prototipo

Se hai installato l'estensione Data Connect VS Code, gli SDK generati saranno sempre aggiornati.

Se non utilizzi l'estensione Data Connect VS Code, puoi utilizzare l'interfaccia a riga di comando di Firebase per mantenere aggiornati gli SDK generati.

firebase dataconnect:sdk:generate --watch

Genera SDK nelle pipeline di build

Puoi utilizzare l'interfaccia a riga di comando di Firebase per generare gli SDK Data Connect nei processi di build CI/CD.

firebase dataconnect:sdk:generate

Configura il codice client

Inizializza l'app Data Connect

Innanzitutto, inizializza l'app seguendo le istruzioni di configurazione standard di Firebase.

Poi, installa il Data Connect plug-in:

flutter pub add firebase_data_connect

Inizializza l'SDK Flutter Data Connect

Inizializza l'istanza Data Connect utilizzando le informazioni che hai utilizzato per configurare Data Connect (tutte disponibili nella scheda Data Connect della consoleFirebase ).

Importa le librerie

Sono necessari due set di importazioni per inizializzare il codice client: le importazioni generali Data Connect e le importazioni specifiche dell'SDK generato.

// general imports
import 'package:firebase_data_connect/firebase_data_connect.dart';

// generated queries and mutations from SDK
import 'generated/movies.dart';

Utilizza le query lato client

Il codice generato include già i riferimenti alle query predefiniti. Devi solo importarli e chiamare execute su di essi.

import 'generated/movies.dart';

await MoviesConnector.instance.listMovies().execute();

Chiama i metodi di query dell'SDK

Ecco un esempio di utilizzo di queste funzioni di scorciatoia per le azioni:

import 'generated/movies.dart';

function onBtnClick() {
  // This will call the generated Dart from the CLI and then make an HTTP request to the server.
  MoviesConnector.instance.listMovies().execute().then(data => showInUI(data)); // == MoviesConnector.instance.listMovies().ref().execute();
}

Campi facoltativi

Alcune query potrebbero avere campi facoltativi. In questi casi, l'SDK Flutter espone un metodo di creazione e deve essere impostato separatamente.

Ad esempio, il campo rating è facoltativo quando chiami createMovie, quindi devi fornirlo nella funzione di creazione.

await MoviesConnector.instance.createMovie({ title: 'Empire Strikes Back', releaseYear: 1980, genre: "Sci-Fi"}).rating(5).execute();

Iscriviti alle modifiche

Puoi iscriverti alle modifiche (che verranno aggiornate ogni volta che esegui una query).

QueryRef<ListMoviesData, void> listRef = MoviesConnector.instance.listMovies().ref();

// subscribe will immediately invoke the query if no execute was called on it previously.
listRef.subscribe().listen((data) {
  updateUIWithMovies(data.movies);
});

await MoviesConnector.instance.createMovie({ title: 'Empire Strikes Back', releaseYear: 1980, genre: "Sci-Fi" }).rating(5).execute();
await listRef.execute(); // will update the subscription above`

Gestisci le modifiche ai campi di enumerazione

Lo schema di un'app può contenere enumerazioni, a cui è possibile accedere tramite le query GraphQL.

Man mano che il design di un'app cambia, puoi aggiungere nuovi valori supportati per l'enumerazione. Ad esempio, supponiamo che in un secondo momento nel ciclo di vita dell'applicazione tu decida di aggiungere un valore FULLSCREEN all'enumerazione AspectRatio.

Nel flusso di lavoro Data Connect, puoi utilizzare gli strumenti di sviluppo locali per aggiornare le query e gli SDK.

Tuttavia, prima di rilasciare una versione aggiornata dei client, i client di cui è stato eseguito il deployment precedente potrebbero non funzionare.

Esempio di implementazione resiliente

L'SDK generato impone la gestione dei valori sconosciuti. Ciò significa che il codice client deve decomprimere l'oggetto EnumValue in Known o Unknown.

final result = await MoviesConnector.instance.listMovies().execute();

if (result.data != null && result.data!.isNotEmpty) {
  handleEnumValue(result.data![0].aspectratio);
}

void handleEnumValue(EnumValue<AspectRatio> aspectValue) {
  if (aspectValue.value != null) {
    switch(aspectValue.value!) {
      case AspectRatio.ACADEMY:
        print("This movie is in Academy aspect");
        break;
      case AspectRatio.WIDESCREEN:
        print("This movie is in Widescreen aspect");
        break;
      case AspectRatio.ANAMORPHIC:
        print("This movie is in Anamorphic aspect");
        break;
      case AspectRatio.IMAX:
        print("This movie is in IMAX aspect");
    }
  } else {
    print("Unknown aspect ratio detected: ${aspectValue.stringValue}");
  }
}

Attiva la memorizzazione nella cache lato client

Data Connect ha una funzionalità di memorizzazione nella cache lato client facoltativa, che puoi attivare modificando il file connector.yaml. Quando questa funzionalità è attivata, gli SDK client generati memorizzano nella cache localmente le risposte alle query, il che può ridurre il numero di richieste di database effettuate dall'app e consentire alle parti dell'app dipendenti dal database di funzionare quando la disponibilità della rete viene interrotta.

Per attivare la memorizzazione nella cache lato client, aggiungi una configurazione di memorizzazione nella cache client alla configurazione del connettore:

generate:
  javascriptSdk:
    outputDir: ../dart/
    package: "dataconnect_generated"
    clientCache:
      maxAge: 5s
      storage: memory

Questa configurazione ha due parametri, entrambi facoltativi:

  • maxAge: l'età massima di una risposta memorizzata nella cache prima che l'SDK client recuperi i valori aggiornati. Esempi: "0", "30s", "1h30m".

    Il valore predefinito di maxAge è 0, il che significa che le risposte vengono memorizzate nella cache, ma l'SDK client recupererà sempre i valori aggiornati. I valori memorizzati nella cache verranno utilizzati solo quando CACHE_ONLY viene specificato per execute() e il risultato iniziale restituito da subscribe().

  • storage: l'SDK client può essere configurato per memorizzare nella cache le risposte in persistent storage o in memory. I risultati memorizzati nella cache in persistent storage verranno mantenuti dopo il riavvio dell'app. Quando il target è Android o iOS, il valore predefinito è persistent. Quando il target sono i browser web, è supportato solo memory storage.

Dopo aver aggiornato la configurazione della memorizzazione nella cache del connettore, rigenera gli SDK client e ricompila l'app. Una volta fatto, execute() e subscribe() memorizzeranno nella cache le risposte e utilizzeranno i valori memorizzati nella cache in base alla policy configurata. In genere, questa operazione viene eseguita automaticamente, senza ulteriori interventi da parte tua. Tuttavia, tieni presente quanto segue:

  • Il comportamento predefinito di execute() è quello descritto sopra: se un risultato viene memorizzato nella cache per una query e il valore memorizzato nella cache non è più vecchio di maxAge, viene utilizzato il valore memorizzato nella cache. Questo comportamento predefinito è chiamato policy PREFER_CACHE.

    Puoi anche specificare le singole chiamate a execute() per pubblicare solo i valori memorizzati nella cache (CACHE_ONLY) o per recuperare incondizionatamente i valori aggiornati dal server (SERVER_ONLY).

    await queryRef.execute(fetchPolicy: QueryFetchPolicy.cacheOnly);
    
    await queryRef.execute(fetchPolicy: QueryFetchPolicy.serverOnly);
    
  • Quando chiami subscribe(), restituirà sempre immediatamente i contenuti memorizzati nella cache, se esistono, indipendentemente dall'impostazione maxAge. Le chiamate successive a execute() invieranno una notifica ai listener in base a maxAge configurato.

Utilizza le mutazioni lato client

Le mutazioni sono accessibili nello stesso modo delle query.

await MoviesConnector.instance.createMovie({ title: 'Empire Strikes Back', releaseYear: 1980, genre: "Sci-Fi" }).rating(5).execute();

Crea prototipi e testa le app Flutter

Strumenta i client per utilizzare un emulatore locale

Puoi utilizzare l'emulatore Data Connect, sia dall' estensione Data Connect VS Code sia dall'interfaccia a riga di comando.

La strumentazione dell'app per la connessione all'emulatore è la stessa per entrambi gli scenari.

import 'package:firebase_data_connect/firebase_data_connect.dart';
import 'generated/movies.dart';

MoviesConnector.instance.dataConnect
          .useDataConnectEmulator('127.0.0.1', 9399);

// Make calls from your app
QueryRef<ListMoviesData, void> ref = MoviesConnector.instance.listMovies.ref();

Per passare alle risorse di produzione, inserisci come commento le righe per la connessione all'emulatore.

Tipi di dati nell'SDK Dart

Il server Data Connect rappresenta i tipi di dati GraphQL comuni. Questi sono rappresentati nell'SDK come segue.

Data Connect Tipo Dart
Timestamp firebase_data_connect.Timestamp
Int (32 bit) int
Data DateTime
UUID stringa
Int64 int
In virgola mobile double
Booleano bool
Qualsiasi firebase_data_connect.AnyValue