Utiliser les SDK Android générés

Les SDK client Firebase SQL Connect vous permettent d'appeler vos requêtes et mutations côté serveur directement depuis une application Firebase. Vous générez un SDK client personnalisé en parallèle de la conception des schémas, des requêtes et des mutations que vous déployez sur votre service Firebase SQL Connect.SQL Connect Ensuite, vous intégrez les méthodes de ce SDK à votre logique client.

Comme nous l'avons mentionné ailleurs, il est important de noter que les requêtes et les mutations SQL Connectne sont pas envoyées par le code client et exécutées sur le serveur. En revanche, lors du déploiement, les opérations SQL Connect sont stockées sur le serveur, comme Cloud Functions. Cela signifie que vous devez déployer les modifications correspondantes côté client pour éviter de perturber les utilisateurs existants (par exemple, sur les anciennes versions de l'application).

C'est pourquoi SQL Connect vous fournit un environnement de développement et des outils qui vous permettent de prototyper vos schémas, requêtes et mutations déployés sur le serveur. Il génère également automatiquement des SDK côté client pendant que vous créez votre prototype.

Une fois que vous avez effectué des mises à jour itératives de vos applications de service et client, les mises à jour côté serveur et côté client sont prêtes à être déployées.

Qu'est-ce que le workflow de développement client ?

Si vous avez suivi la section Premiers pas, vous avez découvert le flux de développement global pour SQL Connect. Ce guide fournit des informations plus détaillées sur la génération de SDK Android à partir de votre schéma, ainsi que sur l'utilisation des requêtes et mutations client.

En résumé, pour utiliser les SDK Android générés dans vos applications clientes, vous devez suivre les étapes préalables suivantes :

  1. Ajoutez Firebase à votre application Android.
  2. Configurez SQL Connect en tant que dépendance dans Gradle.
  3. Ajoutez le plug-in Gradle de sérialisation Kotlin et la dépendance Gradle.

Puis :

  1. Développez le schéma de votre application.
  2. Configurez la génération du SDK :

  3. Initialisez votre code client et importez les bibliothèques.

  4. Implémentez les appels aux requêtes et aux mutations.

  5. Configurez et utilisez l'émulateur SQL Connect, puis itérez.

Générer votre SDK Kotlin

Utilisez l'interface de ligne de commande Firebase pour configurer les SDK générés SQL Connect dans vos applications. La commande init devrait détecter toutes les applications du dossier actuel et installer automatiquement les SDK générés.

firebase init dataconnect:sdk

Mettre à jour les SDK lors du prototypage

Si l'extension SQL Connect VS Code est installée, elle maintient toujours les SDK générés à jour.

Si vous n'utilisez pas l'extension SQL Connect VS Code, vous pouvez utiliser l'interface de ligne de commande Firebase pour maintenir à jour les SDK générés.

firebase dataconnect:sdk:generate --watch

Générer des SDK dans des pipelines de compilation

Vous pouvez utiliser la CLI Firebase pour générer des SDK SQL Connect dans les processus de compilation CI/CD.

firebase dataconnect:sdk:generate

Configurer le code client

Intégrer SQL Connect dans votre code client

Pour configurer votre code client afin d'utiliser SQL Connect et votre SDK généré, commencez par suivre les instructions de configuration Firebase standards.

Ajoutez ensuite les éléments suivants à la section plugins de app/build.gradle.kts :

// The Firebase team tests with version 1.8.22; however, other 1.8 versions,
// and all newer versions are expected work too.
kotlin("plugin.serialization") version "1.8.22" // MUST match the version of the Kotlin compiler

Ajoutez ensuite les éléments suivants à la section dependencies de app/build.gradle.kts :

implementation(platform("com.google.firebase:firebase-bom:34.12.0"))
implementation("com.google.firebase:firebase-dataconnect")
implementation("com.google.firebase:firebase-auth") // Optional
implementation("com.google.firebase:firebase-appcheck") // Optional
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3") // Newer versions should work too
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core:1.5.1") // Newer versions should work too

Initialiser le SDK Android SQL Connect

Initialisez votre instance SQL Connect à l'aide des informations que vous avez utilisées pour configurer SQL Connect (toutes disponibles dans l'onglet SQL Connect de la console Firebase).

Objet ConnectorConfig

Le SDK nécessite un objet de configuration du connecteur.

Cet objet est généré automatiquement à partir de serviceId et location dans dataconnect.yaml, et connectorId dans connector.yaml.

Obtenir une instance de connecteur

Maintenant que vous avez configuré un objet de configuration, obtenez une instance de connecteur SQL Connect. Le code de votre connecteur sera généré par l'émulateur SQL Connect. Si le nom de votre connecteur est movies et que le package Kotlin est com.myapplication, comme spécifié dans connector.yaml, récupérez l'objet du connecteur en appelant :

val connector = com.myapplication.MoviesConnector.instance

Utiliser des requêtes et des mutations à partir de votre SDK Android

L'objet de connecteur vous permet d'exécuter des requêtes et des mutations telles que définies dans le code source GraphQL. Supposons que votre connecteur comporte les opérations suivantes :

mutation createMovie($title: String!, $releaseYear: Int!, $genre: String!, $rating: Int!) {
  movie_insert(data: {
    title: $title
    releaseYear: $releaseYear
    genre: $genre
    rating: $rating
  })
}

query getMovieByKey($key: Movie_Key!) {
  movie(key: $key) { id title }
}

query listMoviesByGenre($genre: String!) {
  movies(where: {genre: {eq: $genre}}) {
    id
    title
  }
}

Vous pouvez ensuite créer et récupérer un film comme suit :

val connector = MoviesConnector.instance

val addMovieResult1 = connector.createMovie.execute(
  title = "Empire Strikes Back",
  releaseYear = 1980,
  genre = "Sci-Fi",
  rating = 5
)

val movie1 = connector.getMovieByKey.execute(addMovieResult1.data.key)

println("Empire Strikes Back: ${movie1.data.movie}")

Vous pouvez également récupérer plusieurs films :

val connector = MoviesConnector.instance

val addMovieResult2 = connector.createMovie.execute(
  title="Attack of the Clones",
  releaseYear = 2002,
  genre = "Sci-Fi",
  rating = 5
)

val listMoviesResult = connector.listMoviesByGenre.execute(genre = "Sci-Fi")

println(listMoviesResult.data.movies)

Vous pouvez également collecter un Flow qui ne produira un résultat que lorsqu'un nouveau résultat de requête sera récupéré à l'aide d'un appel à la méthode execute() de la requête.

val connector = MoviesConnector.instance

connector.listMoviesByGenre.flow(genre = "Sci-Fi").collect { data ->
  println(data.movies)
}

connector.createMovie.execute(
  title="A New Hope",
  releaseYear = 1977,
  genre = "Sci-Fi",
  rating = 5
)

connector.listMoviesByGenre.execute(genre = "Sci-Fi") // will cause the Flow to get notified

Gérer les modifications apportées aux champs d'énumération

Le schéma d'une application peut contenir des énumérations, auxquelles vos requêtes GraphQL peuvent accéder.

À mesure que la conception d'une application change, vous pouvez ajouter de nouvelles valeurs d'énumération acceptées. Par exemple, imaginez que, plus tard dans le cycle de vie de votre application, vous décidiez d'ajouter une valeur FULLSCREEN à l'énumération AspectRatio.

Dans le workflow SQL Connect, vous pouvez utiliser des outils de développement local pour mettre à jour vos requêtes et vos SDK.

Toutefois, avant de publier une version mise à jour de vos clients, il est possible que les anciens clients déployés ne fonctionnent plus.

Exemple d'implémentation résiliente

Le SDK généré force la gestion des valeurs inconnues, car le code du client doit décompresser l'objet EnumValue, qui est soit EnumValue.Known pour les valeurs d'énumération connues, soit EnumValue.Unknown pour les valeurs inconnues.

val result = connector.listMoviesByAspectRatio.execute(AspectRatio.WIDESCREEN)
val encounteredAspectRatios = mutableSetOf<String>()

result.data.movies
  .mapNotNull { it.otherAspectRatios }
  .forEach { otherAspectRatios ->
    otherAspectRatios
      .filterNot { it.value == AspectRatio.WIDESCREEN }
      .forEach {
        when (it) {
          is EnumValue.Known -> encounteredAspectRatios.add(it.value.name)
          is EnumValue.Unknown ->
            encounteredAspectRatios.add("[unknown ratio: ${it.stringValue}]")
        }
      }
  }

println(
  "Widescreen movies also include additional aspect ratios: " +
    encounteredAspectRatios.sorted().joinToString()
)

Activer la mise en cache côté client

SQL Connect dispose d'une fonctionnalité de mise en cache côté client facultative que vous pouvez activer en modifiant le fichier connector.yaml. Lorsque cette fonctionnalité est activée, les SDK clients générés mettent en cache localement les réponses aux requêtes, ce qui peut réduire le nombre de requêtes de base de données effectuées par votre application et permettre aux parties de votre application qui dépendent de la base de données de fonctionner en cas d'interruption de la disponibilité du réseau.

Pour activer la mise en cache côté client, ajoutez une configuration de mise en cache client à la configuration de votre connecteur :

generate:
  kotlinSdk:
    outputDir: "../android"
    package: "com.google.firebase.dataconnect.generated"
    clientCache:
      maxAge: 5s
      storage: persistent

Cette configuration comporte deux paramètres, tous deux facultatifs :

  • maxAge : âge maximal d'une réponse mise en cache avant que le SDK client récupère de nouvelles valeurs. Exemples : "0", "30s", "1h30m".

    La valeur par défaut de maxAge est 0, ce qui signifie que les réponses sont mises en cache, mais que le SDK client récupère toujours des valeurs récentes. Les valeurs mises en cache ne seront utilisées que lorsque CACHE_ONLY est défini sur execute().

  • storage : le SDK client peut être configuré pour mettre en cache les réponses dans le stockage persistent ou dans memory. Les résultats mis en cache dans le stockage persistent persisteront lors des redémarrages de l'application. Dans les SDK Android, la valeur par défaut est persistent.

Après avoir mis à jour la configuration de la mise en cache de votre connecteur, régénérez vos SDK client et recompilez votre application. Une fois cette opération effectuée, execute() mettra en cache les réponses et utilisera les valeurs mises en cache conformément à la règle que vous avez configurée. Cette opération est généralement automatique et ne nécessite aucune action de votre part. Toutefois, notez les points suivants :

  • Le comportement par défaut de execute() est décrit ci-dessus : si un résultat est mis en cache pour une requête et que la valeur mise en cache n'est pas antérieure à maxAge, utilisez la valeur mise en cache. Ce comportement par défaut est appelé règle PREFER_CACHE.

    Vous pouvez également spécifier des appels individuels de execute() pour ne diffuser que les valeurs mises en cache (CACHE_ONLY) ou pour récupérer inconditionnellement les valeurs récentes du serveur (SERVER_ONLY).

    val queryResult = queryRef.execute(QueryRef.FetchPolicy.CACHE_ONLY)
    
    val queryResult = queryRef.execute(QueryRef.FetchPolicy.SERVER_ONLY)
    

    Prototyper et tester votre application Android

    Instrumenter les clients pour utiliser un émulateur local

    Vous pouvez utiliser l'émulateur SQL Connect, que ce soit à partir de l'extension VS Code SQL Connect ou de la CLI.

    L'instrumentation de l'application pour se connecter à l'émulateur est la même dans les deux scénarios.

    val connector = MoviesConnector.instance
    
    // Connect to the emulator on "10.0.2.2:9399"
    connector.dataConnect.useEmulator()
    
    // (alternatively) if you're running your emulator on non-default port:
    connector.dataConnect.useEmulator(port = 9999)
    
    // Make calls from your app
    
    

    Pour passer aux ressources de production, mettez en commentaire les lignes de connexion à l'émulateur.

    Types SQL dans les SDK SQL Connect

    Le serveur SQL Connect représente les types de données GraphQL courants et personnalisés. Elles sont représentées dans le SDK comme suit.

    Type SQL Connect Kotlin
    Chaîne Chaîne
    Int Int (entier 32 bits)
    Float Double (float 64 bits)
    Booléen Booléen
    UUID java.util.UUID
    Date com.google.firebase.dataconnect.LocalDate (était java.util.Date jusqu'à la version 16.0.0-beta03)
    Horodatage com.google.firebase.Timestamp
    Int64 Long
    Tous com.google.firebase.dataconnect.AnyValue