Можете ли вы написать Облачные функции Firebase в Dart?

Да, вы можете, и вот как это сделать.

Статья обновлена ​​до Firebase CLI версии 8.4.

Настройка Firebase

Установите Node.js и Firebase CLI, если вы еще этого не сделали:

npm install -g firebase-tools

Затем войдите в Firebase Console и создайте новый проект (или выберите тот, который хотите использовать). Потому что позже в этом руководстве мы продемонстрируем функцию, которая обращается к Cloud Firestore, создает такую ​​базу данных в выбранном вами регионе и запоминает этот регион. Вы должны развернуть свои функции в том же регионе, что и ваша база данных, если вы не хотите платить за трафик данных между разными регионами!

Вернувшись на терминал, также войдите в Firebase здесь:

firebase login

Затем, наконец, что не менее важно, настройте проект functions в вашем текущем каталоге:

firebase init functions

Выберите проект Firebase, который вы создали ранее, выберите «JavaScript» в качестве языка и снимите флажок «ESLint» (который нам не нужен, поскольку мы не пишем JavaScript самостоятельно). Затем разрешите firebase загрузить все зависимости через npm и подождите, пока он загрузит половину Интернета.

Этот процесс создал пустой файл firebase.json и каталог с именем functions, который содержит типичный проект узла с файлом package.json, каталог node_modules и файл index.js, содержащий пример «hello world».

Откройте index.js и раскомментируйте пример кода. Затем протестируйте созданную функцию, чтобы убедиться, что ваша установка прошла успешно, запустив:

npm run serve

Эмулятор Firebase должен распечатать URL-адрес для доступа к облачной функции. На моей машине это http: // localhost: 5001 / ‹projectname› / us-central1 / helloWorld. Он также запускает модный веб-интерфейс для своего эмулятора на http: // localhost: 4000 /. Он даже автоматически принимает изменения в index.js во время работы, что очень приятно. В конце концов остановите сервер.

Перейти на Dart

Затем настройте проект Dart.

Установите Dart SDK, если вы еще этого не сделали.

Создайте новый pubspec.yaml файл в каталоге functions со следующим содержимым:

name: functions
version: 1.0.0
environment:
  sdk: ‘>=2.8.0 <3.0.0’
dependencies:
  firebase_functions_interop: ^1.0.2
dev_dependencies:
  build_runner: ^1.9.0
  build_node_compilers: ^0.2.4

Запустите pub get, чтобы загрузить все зависимости.

Создайте каталог с именем node и создайте внутри этой папки файл с именем index.dart, который выглядит следующим образом:

import 'package:firebase_functions_interop/firebase_functions_interop.dart';
void main() {
  functions[‘moin’] = functions
    .region('europe-west3')
    .https.onRequest(greet);
}
void greet(ExpressHttpRequest request) {
  request.response
    ..writeln('Moin, moin!')
    ..close();
}

Примечание. Вы должны заменить europe-west3 на свой регион или опустить эту строку.

Создайте еще один файл с именем build.yaml с этим содержимым:

targets:
  $default:
    sources:
      — node/**
      — lib/**
    builders:
      build_node_compilers|entrypoint:
        options:
          compiler: dart2js

Добавьте эти строки в .gitignore:

ui-debug.log
build/
.dart_tool/
.packages

Теперь беги

pub run build_runner build -o node:build

Это преобразует node/index.dart в build/index.dart.js. Соглашение об использовании каталога node вместо обычного каталога bin было встроено в пакет оболочки NodeJS, который используется внутри компании. Он выполняет тяжелую работу по переводу Dart на JavaScript. Вы можете добавить другие файлы Dart в lib, если хотите.

Затем измените package.json и добавьте:

  "main": "build/index.dart.js"

Вы можете удалить index.js. Царство JavaScript подходит к концу.

Затем снова запустите npm run serve. При доступе к показанному URL-адресу появляется текст «Моин, мойн!» должен отображаться. Мы успешно создали облачную функцию в Dart! В конце концов остановите сервер.

Развертывание функции

Замените содержимое firebase.json этим содержимым:

{
  "functions": {
    "ignore": [
      ".dart_tool",
      ".packages",
      "**/build/*.map",
      "**/build/packages",
      "build.yaml",
      "node",
      "node_modules",
      "pubspec.*"
    ]
  }
}

Теперь давайте развернем облачную функцию в Firebase:

npm run deploy

Теперь ваша функция должна быть запущена.

Обратите внимание, что по умолчанию package.json настроен на использование Node.js версии 8. Эта версия скоро будет отключена Google. Вы должны перейти на версию 10. Однако вам придется заплатить за использование этой версии.

Рабочий процесс разработки

Для локальной разработки используйте watch вместо build, например:

pub run build_runner watch -o node:build

и - во втором терминале - запустите:

npm run serve

Затем измените источник Dart и обратите внимание на build_runner, чтобы перекомпилировать исходный код Dart, и сервер разработки Firebase, чтобы перезагрузить функцию JavaScript. Теперь вы готовы оставить мир JavaScript позади и использовать Dart только для клиентской и серверной разработки. Счастливые времена!

Интеграция Firestore

Давайте определим триггер Firestore, который будет автоматически вызываться каждый раз, когда новый документ добавляется в foo коллекцию. Он создает аналогичный документ в коллекции bar, который имеет то же свойство name, что и документ в foo.

Сначала инициализируйте, загрузите и запустите эмулятор Firestore:

firebase init emulators
firebase emulators:start

Модный интерфейс доступен по адресу http: // localhost: 4000 /.

Теперь замените index.dart на следующий код и убедитесь, что Дротик build_runner все еще наблюдает за вами.

import 'package:firebase_functions_interop/firebase_functions_interop.dart';
void main() {
  functions['foo'] = functions
    .region('europe-west3')
    .firestore.document('/foo/{id}').onCreate(createHook);
}
Future<void> createHook(DocumentSnapshot snapshot, EventContext context) async {
  final name = snapshot.data.getString('name');
  final data = DocumentData.fromMap({'name': name});
  await snapshot.firestore.collection('/bar').add(data);
}

Примечание. Убедитесь, что функция работает в том же регионе, что и ваше хранилище данных! Также обратите внимание, что имя региона магазина и имя региона функции могут не совпадать.

Поскольку и эмулятор Firebase, и наблюдатель сборки работают, сохранение файла Dart должно автоматически (повторно) повторно развернуть вашу функцию, и вы можете пойти и протестировать его, вручную создав новый документ в foo, добавив как минимум свойство name. к этому документу. Затем переключитесь на bar и обратите внимание, что наша функция успешно создала документ.

В последний раз разверните:

npm run deploy

Теперь перейдите в консоль Firebase, откройте базу данных Firestore и проверьте триггер, создав foo/<id> документ со свойством name, и проследите за созданием нового bar/<id> документа с аналогичным свойством name. <id> обозначает автоматически созданный идентификатор документа.

Сотрясение

В ICNH мы создаем приложения Flutter для развлечения и получения прибыли, и нам нравится использовать Firebase в качестве простой в использовании серверной части. Он очень хорошо интегрирован с Flutter, потому что Google предоставляет готовые к использованию пакеты для большинства аспектов Firebase. Для большинства мобильных приложений нам также необходимо настроить серверную часть. Использование того же языка программирования для разработки сервера, что и для разработки клиента, действительно помогает сделать этот процесс намного приятнее.

Мы успешно создали собственный бэкэнд для приложения Flutter, используя только Dart.

Исходный код