Как использовать сгенерированные SDK Flutter

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

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

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

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

Как выглядит процесс разработки клиента?

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

Чтобы использовать сгенерированные SDK Flutter в клиентских приложениях, выполните следующие действия:

  1. Добавьте Firebase в приложение Flutter.
  2. Установите flutterfire CLI dart pub global activate flutterfire_cli.
  3. Выполните команду flutterfire configure.

Затем:

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

    • С помощью кнопки Add SDK to app (Добавить SDK в приложение) в расширении SQL Connect для VS Code.
    • Обновите connector.yaml.
  3. Инициализируйте клиентский код и импортируйте библиотеки.

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

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

Как сгенерировать Flutter SDK

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

firebase init dataconnect:sdk

Обновление SDK при создании прототипов

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

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

firebase dataconnect:sdk:generate --watch

Генерируйте SDK в конвейерах сборки

Вы можете использовать интерфейс командной строки Firebase, чтобы генерировать SDK SQL Connect в процессах сборки CI/CD.

firebase dataconnect:sdk:generate

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

Инициализируйте приложение SQL Connect

Сначала инициализируйте приложение, следуя стандартным инструкциям по настройке Firebase.

Затем установите плагин SQL Connect:

flutter pub add firebase_data_connect

Инициализируйте SQL Connect Flutter SDK

Инициализируйте экземпляр SQL Connect, используя информацию, которую вы указали при настройке SQL Connect. Эту информацию можно найти на странице Databases & Storage (Базы данных и хранилище) > SQL Connect (Подключение SQL) в консоли Firebase.

Импорт библиотек

Для инициализации клиентского кода необходимо импортировать два набора: общие импорты SQL Connect и специальные импорты сгенерированного SDK.

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

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

Использование запросов на стороне клиента

В сгенерированном коде уже будут ссылки на запросы. Вам нужно только импортировать их и вызвать для них execute.

import 'generated/movies.dart';

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

Вызов методов запроса SDK

Вот пример использования этих функций:

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

Необязательные поля

В некоторых запросах могут быть необязательные поля. В таких случаях Flutter SDK предоставляет метод builder, который нужно настроить отдельно.

Например, поле rating является необязательным при вызове createMovie, поэтому его нужно указать в функции builder.

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

Подписаться на изменения

Подробнее о том, как получать обновления от SQL Connect в реальном времени…

Как обрабатывать изменения в полях перечисления

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

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

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

Однако до выпуска обновленной версии клиентов старые развернутые клиенты могут перестать работать.

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

Сгенерированный SDK принудительно обрабатывает неизвестные значения. Это означает, что код клиента должен распаковать объект EnumValue в Known или 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}');
  }
}

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

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

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

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

В этой конфигурации есть два необязательных параметра:

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

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

  • storage. Клиентский SDK можно настроить так, чтобы он кешировал ответы в хранилище persistent или memory. Результаты, сохраненные в хранилище persistent, не будут удалены при перезапуске приложения. При таргетинге на Android или iOS по умолчанию используется persistent. При таргетинге на веб-браузеры поддерживается только хранилище memory.

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

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

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

    await queryRef.execute(fetchPolicy: QueryFetchPolicy.cacheOnly);
    
    await queryRef.execute(fetchPolicy: QueryFetchPolicy.serverOnly);
    
  • При вызове subscribe() всегда сразу возвращается кешированный контент, если он есть, независимо от значения maxAge. Последующие вызовы execute() будут уведомлять прослушиватели в соответствии с настроенным значением maxAge.

Используйте мутации на стороне клиента

Мутации доступны так же, как и запросы.

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

Создание прототипов и тестирование приложений Flutter

Как настроить клиенты для использования локального эмулятора

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

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

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

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

Типы данных в Dart SDK

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

Тип SQL Connect Dart
Временная метка firebase_data_connect.Timestamp
Int (32-битное) int
Дата DateTime
UUID string
Int64 int
Число с плавающей запятой double
Логическое значение bool
Любые firebase_data_connect.AnyValue