Можете ли вы написать Облачные функции 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.