Используйте сгенерированные Android SDK

SDK клиента Firebase SQL Connect позволяют вызывать серверные запросы и мутации непосредственно из приложения Firebase. Вы генерируете пользовательский SDK параллельно с проектированием схем, запросов и мутаций, которые развертываете в своей службе SQL Connect . Затем вы интегрируете методы из этого SDK в свою клиентскую логику.

Как мы уже упоминали ранее, важно отметить, что запросы и мутации SQL Connect не отправляются клиентским кодом и не выполняются на сервере. Вместо этого, при развертывании операции SQL Connect хранятся на сервере, как и в Cloud Functions. Это означает, что вам необходимо развернуть соответствующие изменения на стороне клиента, чтобы избежать нарушения работы существующих пользователей (например, в старых версиях приложения).

Именно поэтому SQL Connect предоставляет вам среду разработки и инструменты, позволяющие создавать прототипы развернутых на сервере схем, запросов и мутаций. Он также автоматически генерирует SDK для клиентской части во время создания прототипов.

После внесения изменений в ваши сервисные и клиентские приложения, обновления как на стороне сервера, так и на стороне клиента готовы к развертыванию.

Каков рабочий процесс разработки клиентской части?

If you followed the Get started , you were introduced to the overall development flow for SQL Connect . In this guide, you'll find more detailed information about generating Android SDKs from your schema and working with client queries and mutations.

Вкратце, для использования сгенерированных Android SDK в клиентских приложениях вам необходимо выполнить следующие предварительные шаги:

  1. Добавьте Firebase в свое Android- приложение.
  2. Настройте SQL Connect как зависимость в Gradle.
  3. Добавьте плагин Kotlin Serialization и зависимость Gradle.

Затем:

  1. Разработайте схему вашего приложения.
  2. Настройка генерации SDK:

  3. Инициализируйте клиентский код и импортируйте библиотеки .

  4. Реализуйте вызовы запросов и мутаций .

  5. Настройте и используйте эмулятор SQL Connect и выполните итерации.

Сгенерируйте свой SDK на Kotlin.

Используйте Firebase CLI для настройки сгенерированных SQL Connect SDK в ваших приложениях. Команда init должна обнаружить все приложения в текущей папке и автоматически установить сгенерированные SDK.

firebase init dataconnect:sdk

Обновляйте SDK во время прототипирования.

Если у вас установлено расширение SQL Connect для VS Code, оно всегда будет поддерживать сгенерированные SDK в актуальном состоянии.

Если вы не используете расширение SQL Connect для VS Code, вы можете использовать Firebase CLI для обновления сгенерированных SDK.

firebase dataconnect:sdk:generate --watch

Генерация SDK в конвейерах сборки

С помощью Firebase CLI можно генерировать SDK SQL Connect в процессах сборки CI/CD.

firebase dataconnect:sdk:generate

Настройка клиентского кода

Интегрируйте SQL Connect в клиентский код.

Чтобы настроить клиентский код для использования SQL Connect и сгенерированного SDK, сначала следуйте стандартным инструкциям по настройке Firebase .

Затем добавьте следующее в раздел plugins в файле 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

Затем добавьте следующее в раздел dependencies в файле 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

Инициализируйте SDK SQL Connect для Android.

Инициализируйте свой экземпляр SQL Connect используя информацию, которую вы использовали для настройки SQL Connect (вся информация доступна на вкладке SQL Connect в консоли Firebase ).

Объект ConnectorConfig

Для работы SDK требуется объект конфигурации коннектора.

Этот объект генерируется автоматически на основе serviceId и location в dataconnect.yaml , а также connectorId в connector.yaml .

Получение экземпляра коннектора

Now that you've set up a configuration object, get a SQL Connect connector instance. The code for your connector will be generated by the SQL Connect emulator. If your connector name is movies and the Kotlin package is com.myapplication , as specified in connector.yaml , then retrieve the connector object by calling:

val connector = com.myapplication.MoviesConnector.instance

Используйте запросы и мутации из вашего Android SDK.

С помощью объекта коннектора вы можете выполнять запросы и мутации, определенные в исходном коде GraphQL. Предположим, ваш коннектор имеет следующие определенные операции:

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

Затем вы можете создать и получить доступ к фильму следующим образом:

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

Вы также можете загрузить несколько фильмов:

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)

Также можно создать Flow , который будет выдавать результат только тогда, когда будет получен новый результат запроса с помощью вызова метода execute() этого запроса.

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

Обработка изменений в полях перечисления

Схема приложения может содержать перечисления , к которым можно получить доступ с помощью запросов GraphQL .

По мере изменения дизайна приложения вы можете добавлять новые значения, поддерживаемые перечислениями. Например, представьте, что на более позднем этапе жизненного цикла вашего приложения вы решили добавить значение FULLSCREEN в перечисление AspectRatio .

В рабочем процессе SQL Connect вы можете использовать локальные инструменты разработки для обновления ваших запросов и SDK.

Однако, прежде чем вы выпустите обновленную версию своих клиентов, старые развернутые клиенты могут перестать работать.

Пример отказоустойчивой реализации

The generated SDK forces handling of unknown values as the customer's code must unwrap the EnumValue object, which is either EnumValue.Known for known enum values or EnumValue.Unknown for unknown values.

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()
)

Включите кэширование на стороне клиента.

SQL Connect имеет дополнительную функцию кэширования на стороне клиента, которую можно включить, отредактировав файл connector.yaml . При включении этой функции сгенерированные клиентские SDK будут локально кэшировать ответы на запросы, что может уменьшить количество запросов к базе данных, выполняемых вашим приложением, и позволит зависимым от базы данных частям вашего приложения работать даже при перебоях в сети.

Чтобы включить кэширование на стороне клиента, добавьте конфигурацию кэширования клиента в конфигурацию коннектора:

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

Данная конфигурация имеет два параметра, оба необязательные:

  • maxAge : Максимальный срок хранения кэшированного ответа до того, как клиентский SDK получит новые значения. Примеры: "0", "30 с", "1 ч 30 мин".

    Значение по умолчанию для maxAge равно 0 , что означает, что ответы кэшируются, но клиентский SDK всегда будет получать актуальные значения. Кэшированные значения будут использоваться только в том случае, если для execute() указан параметр CACHE_ONLY .

  • storage : The client SDK can be configured to cache responses either in persistent storage or in memory . Results cached in persistent storage will persist across app restarts. In Android SDKs, the default is persistent .

После обновления конфигурации кэширования вашего коннектора перегенерируйте клиентские SDK и пересоберите приложение. После этого execute() будет кэшировать ответы и использовать кэшированные значения в соответствии с настроенной вами политикой. Обычно это происходит автоматически, без каких-либо дополнительных действий с вашей стороны; однако обратите внимание на следующее:

  • Поведение функции execute() по умолчанию описано выше: если результат запроса кэширован и кэшированное значение не старше значения maxAge , то используется кэшированное значение. Это поведение по умолчанию называется политикой PREFER_CACHE .

    Вы также можете указать отдельным вызовам функции execute() либо предоставлять только кэшированные значения ( CACHE_ONLY ), либо безусловно получать свежие значения с сервера ( SERVER_ONLY ).

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

    Создайте прототип и протестируйте свое Android-приложение.

    Для обеспечения возможности использования локального эмулятора клиенты должны быть оснащены соответствующими инструментами.

    Вы можете использовать эмулятор SQL Connect как через расширение SQL Connect для VS Code, так и через интерфейс командной строки.

    Процесс подключения приложения к эмулятору одинаков в обоих случаях.

    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
    
    

    Чтобы переключиться на производственные ресурсы, закомментируйте строки, отвечающие за подключение к эмулятору.

    Типы SQL в SDK SQL Connect

    Сервер SQL Connect представляет собой стандартные и пользовательские типы данных GraphQL. В SDK они представлены следующим образом.

    Тип SQL Connect Котлин
    Нить Нить
    Интерн. Int (32-битное целое число)
    Плавать Число с плавающей запятой типа Double (64-битное число)
    Логический Логический
    UUID java.util.UUID
    Дата com.google.firebase.dataconnect.LocalDate (ранее java.util.Date до версии 16.0.0-beta03)
    Отметка времени com.google.firebase.Timestamp
    Int64 Длинный
    Любой com.google.firebase.dataconnect.AnyValue