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

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

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

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

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

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

Если вы следовали инструкциям в разделе «Начало работы» , вы познакомились с общим процессом разработки SQL Connect . В этом руководстве вы найдете более подробную информацию о создании Android SDK на основе вашей схемы, а также о работе с клиентскими запросами и мутациями.

Вкратце, для использования сгенерированных 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.13.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 требуется объект конфигурации коннектора.

This object is automatically generated from serviceId and location in dataconnect.yaml , and connectorId in connector.yaml .

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

Теперь, когда вы настроили объект конфигурации, получите экземпляр коннектора SQL Connect . Код для вашего коннектора будет сгенерирован эмулятором SQL Connect . Если имя вашего коннектора — movies , а пакет Kotlin — com.myapplication , как указано в connector.yaml , то получите объект коннектора, вызвав:

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.

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

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

Сгенерированный SDK принудительно обрабатывает неизвестные значения, поскольку код заказчика должен извлечь объект EnumValue , который имеет значение либо EnumValue.Known для известных значений перечисления, либо EnumValue.Unknown для неизвестных значений.

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 : Клиентский SDK можно настроить для кэширования ответов либо в persistent хранилище, либо в memory . Результаты, кэшированные в persistent хранилище, сохранятся после перезапуска приложения. В Android SDK по умолчанию используется 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