Начало работы: напишите, протестируйте и разверните свои первые функции.


Чтобы начать работу с Cloud Functions , попробуйте поработать с этим руководством, которое начинается с обязательных задач настройки и проходит через создание, тестирование и развертывание двух связанных функций:

  • Функция «добавить сообщение», которая предоставляет URL-адрес, принимающий текстовое значение, и записывает его в Cloud Firestore .
  • Функция «сделать заглавными», которая срабатывает при записи в Cloud Firestore и преобразует текст в заглавные буквы.

Вот полный пример кода, содержащий функции:

Node.js

// The Cloud Functions for Firebase SDK to create Cloud Functions and triggers.
const {logger} = require("firebase-functions");
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");

// The Firebase Admin SDK to access Firestore.
const {initializeApp} = require("firebase-admin/app");
const {getFirestore} = require("firebase-admin/firestore");

initializeApp();

// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addmessage = onRequest(async (req, res) => {
  // Grab the text parameter.
  const original = req.query.text;
  // Push the new message into Firestore using the Firebase Admin SDK.
  const writeResult = await getFirestore()
      .collection("messages")
      .add({original: original});
  // Send back a message that we've successfully written the message
  res.json({result: `Message with ID: ${writeResult.id} added.`});
});

// Listens for new messages added to /messages/:documentId/original
// and saves an uppercased version of the message
// to /messages/:documentId/uppercase
exports.makeuppercase = onDocumentCreated("/messages/{documentId}", (event) => {
  // Grab the current value of what was written to Firestore.
  const original = event.data.data().original;

  // Access the parameter `{documentId}` with `event.params`
  logger.log("Uppercasing", event.params.documentId, original);

  const uppercase = original.toUpperCase();

  // You must return a Promise when performing
  // asynchronous tasks inside a function
  // such as writing to Firestore.
  // Setting an 'uppercase' field in Firestore document returns a Promise.
  return event.data.ref.set({uppercase}, {merge: true});
});

Питон

# The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
from firebase_functions import firestore_fn, https_fn

# The Firebase Admin SDK to access Cloud Firestore.
from firebase_admin import initialize_app, firestore
import google.cloud.firestore

app = initialize_app()


@https_fn.on_request()
def addmessage(req: https_fn.Request) -> https_fn.Response:
    """Take the text parameter passed to this HTTP endpoint and insert it into
    a new document in the messages collection."""
    # Grab the text parameter.
    original = req.args.get("text")
    if original is None:
        return https_fn.Response("No text parameter provided", status=400)

    firestore_client: google.cloud.firestore.Client = firestore.client()

    # Push the new message into Cloud Firestore using the Firebase Admin SDK.
    _, doc_ref = firestore_client.collection("messages").add({"original": original})

    # Send back a message that we've successfully written the message
    return https_fn.Response(f"Message with ID {doc_ref.id} added.")


@firestore_fn.on_document_created(document="messages/{pushId}")
def makeuppercase(event: firestore_fn.Event[firestore_fn.DocumentSnapshot | None]) -> None:
    """Listens for new documents to be added to /messages. If the document has
    an "original" field, creates an "uppercase" field containg the contents of
    "original" in upper case."""

    # Get the value of "original" if it exists.
    if event.data is None:
        return
    try:
        original = event.data.get("original")
    except KeyError:
        # No "original" field, so do nothing.
        return

    # Set the "uppercase" field.
    print(f"Uppercasing {event.params['pushId']}: {original}")
    upper = original.upper()
    event.data.reference.update({"uppercase": upper})

Об этом уроке

Мы выбрали Cloud Firestore и HTTP-триггерные функции для этого примера отчасти потому, что эти фоновые триггеры можно тщательно протестировать с помощью Firebase Local Emulator Suite . Этот набор инструментов также поддерживает Realtime Database , Cloud Storage , PubSub, Auth и HTTP-вызываемые триггеры. Другие типы фоновых триггеров, такие как Remote Config и TestLab, можно протестировать интерактивно с помощью наборов инструментов, не описанных на этой странице.

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

Создать проект Firebase

  1. В консоли Firebase нажмите Добавить проект .

    • Чтобы добавить ресурсы Firebase в существующий проект Google Cloud , введите имя проекта или выберите его из раскрывающегося меню.

    • Чтобы создать новый проект, введите имя проекта. Вы также можете изменить идентификатор проекта, отображаемый под именем проекта.

  2. При появлении соответствующего запроса ознакомьтесь с условиями Firebase и примите их.

  3. Нажмите «Продолжить» .

  4. (Необязательно) Настройте Google Analytics для своего проекта, что обеспечит оптимальную работу с использованием следующих продуктов Firebase: Firebase A/B Testing , Cloud Messaging , Crashlytics , In-App Messaging и Remote Config (включая Personalization ).

    Либо выберите существующую учетную запись Google Analytics , либо создайте новую учетную запись. Если вы создаете новую учетную запись, выберите местоположение отчетов Analytics , затем примите настройки совместного использования данных и условия Google Analytics для вашего проекта.

  5. Нажмите «Создать проект» (или «Добавить Firebase» , если вы добавляете Firebase в существующий проект Google Cloud ).

Firebase автоматически предоставляет ресурсы для вашего проекта Firebase. После завершения процесса вы будете перенаправлены на страницу обзора вашего проекта Firebase в консоли Firebase .

Настройте свою среду и Firebase CLI

Node.js

Вам понадобится среда Node.js для написания функций, а также Firebase CLI для развертывания функций в среде выполнения Cloud Functions . Для установки Node.js и npm рекомендуется Node Version Manager .

После установки Node.js и npm установите Firebase CLI с помощью предпочитаемого вами метода. Чтобы установить CLI с помощью npm, используйте:

npm install -g firebase-tools

Это установит глобально доступную команду firebase. Если команда не сработает, вам может потребоваться изменить разрешения npm . Чтобы обновить firebase-tools до последней версии, повторно запустите ту же команду.

Питон

Вам понадобится среда Python для написания функций, а также Firebase CLI для развертывания функций в среде выполнения Cloud Functions . Мы рекомендуем использовать venv для изоляции зависимостей. Поддерживаются версии Python 3.10 и 3.11.

После установки Python установите Firebase CLI удобным для вас способом.

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

При инициализации Firebase SDK для Cloud Functions вы создаете пустой проект, содержащий зависимости и минимальный пример кода. Если вы используете Node.js, вы можете выбрать TypeScript или JavaScript для составления функций. Для целей этого руководства вам также потребуется инициализировать Cloud Firestore .

Чтобы инициализировать ваш проект:

  1. Запустите firebase login , чтобы войти в систему через браузер и выполнить аутентификацию Firebase CLI.
  2. Перейдите в каталог вашего проекта Firebase.
  3. Запустите firebase init firestore . Для этого руководства вы можете принять значения по умолчанию при запросе правил Firestore и файлов индекса. Если вы еще не использовали Cloud Firestore в этом проекте, вам также нужно будет выбрать начальный режим и местоположение для Firestore, как описано в разделе Начало работы с Cloud Firestore .
  4. Запустите firebase init functions . CLI предложит вам выбрать существующую кодовую базу или инициализировать и назвать новую. Когда вы только начинаете, достаточно одной кодовой базы в расположении по умолчанию; позже, по мере расширения вашей реализации, вам может потребоваться организовать функции в кодовые базы .
  5. CLI предоставляет вам следующие возможности языковой поддержки:

    • JavaScript
    • Машинопись
    • Питон

    Для этого руководства выберите JavaScript или Python . Для разработки на TypeScript см. Write Functions with TypeScript .

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

После успешного выполнения этих команд структура вашего проекта будет выглядеть следующим образом:

Node.js

myproject
+- .firebaserc    # Hidden file that helps you quickly switch between
|                 # projects with `firebase use`
|
+- firebase.json  # Describes properties for your project
|
+- functions/     # Directory containing all your functions code
      |
      +- .eslintrc.json  # Optional file containing rules for JavaScript linting.
      |
      +- package.json  # npm package file describing your Cloud Functions code
      |
      +- index.js      # Main source file for your Cloud Functions code
      |
      +- node_modules/ # Directory where your dependencies (declared in
                        # package.json) are installed

Для Node.js файл package.json , созданный во время инициализации, содержит важный ключ: "engines": {"node": "18"} . Он указывает вашу версию Node.js для написания и развертывания функций. Вы можете выбрать другие поддерживаемые версии .

Питон

myproject
+- .firebaserc    # Hidden file that helps you quickly switch between
|                 # projects with `firebase use`
|
+- firebase.json  # Describes properties for your project
|
+- functions/     # Directory containing all your functions code
      |
      +- main.py      # Main source file for your Cloud Functions code
      |
      +- requirements.txt  #  List of the project's modules and packages 
      |
      +- venv/ # Directory where your dependencies are installed

Импортируйте необходимые модули и инициализируйте приложение.

После завершения задач настройки вы можете открыть исходный каталог и начать добавлять код, как описано в следующих разделах. Для этого примера ваш проект должен импортировать модули Cloud Functions и Admin SDK. Добавьте в исходный файл строки, подобные следующим:

Node.js

// The Cloud Functions for Firebase SDK to create Cloud Functions and triggers.
const {logger} = require("firebase-functions");
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");

// The Firebase Admin SDK to access Firestore.
const {initializeApp} = require("firebase-admin/app");
const {getFirestore} = require("firebase-admin/firestore");

initializeApp();

Питон

# The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
from firebase_functions import firestore_fn, https_fn

# The Firebase Admin SDK to access Cloud Firestore.
from firebase_admin import initialize_app, firestore
import google.cloud.firestore

app = initialize_app()

Эти строки загружают требуемые модули и инициализируют экземпляр admin приложения, из которого можно вносить изменения Cloud Firestore . Везде, где доступна поддержка Admin SDK , как для FCM , Authentication , и Firebase Realtime Database , она обеспечивает мощный способ интеграции Firebase с использованием Cloud Functions .

Firebase CLI автоматически устанавливает модули Firebase Admin SDK и Firebase SDK for Cloud Functions при инициализации проекта. Для получения дополнительной информации о добавлении сторонних библиотек в проект см. Handle Dependencies .

Добавить функцию «добавить сообщение»

Для функции «добавить сообщение» добавьте в исходный файл следующие строки:

Node.js

// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addmessage = onRequest(async (req, res) => {
  // Grab the text parameter.
  const original = req.query.text;
  // Push the new message into Firestore using the Firebase Admin SDK.
  const writeResult = await getFirestore()
      .collection("messages")
      .add({original: original});
  // Send back a message that we've successfully written the message
  res.json({result: `Message with ID: ${writeResult.id} added.`});
});

Питон

@https_fn.on_request()
def addmessage(req: https_fn.Request) -> https_fn.Response:
    """Take the text parameter passed to this HTTP endpoint and insert it into
    a new document in the messages collection."""
    # Grab the text parameter.
    original = req.args.get("text")
    if original is None:
        return https_fn.Response("No text parameter provided", status=400)

    firestore_client: google.cloud.firestore.Client = firestore.client()

    # Push the new message into Cloud Firestore using the Firebase Admin SDK.
    _, doc_ref = firestore_client.collection("messages").add({"original": original})

    # Send back a message that we've successfully written the message
    return https_fn.Response(f"Message with ID {doc_ref.id} added.")

Функция "добавить сообщение" является конечной точкой HTTP. Любой запрос к конечной точке приводит к объектам запроса и ответа, передаваемым обработчику запросов для вашей платформы ( onRequest() или on_request ).

HTTP-функции являются синхронными (аналогично вызываемым функциям ), поэтому следует отправлять ответ как можно быстрее и откладывать работу с помощью Cloud Firestore . HTTP-функция "add message" передает текстовое значение в конечную точку HTTP и вставляет его в базу данных по пути /messages/:documentId/original .

Добавить функцию «сделать заглавными»

Для функции «сделать заглавными» добавьте следующие строки в исходный файл:

Node.js

// Listens for new messages added to /messages/:documentId/original
// and saves an uppercased version of the message
// to /messages/:documentId/uppercase
exports.makeuppercase = onDocumentCreated("/messages/{documentId}", (event) => {
  // Grab the current value of what was written to Firestore.
  const original = event.data.data().original;

  // Access the parameter `{documentId}` with `event.params`
  logger.log("Uppercasing", event.params.documentId, original);

  const uppercase = original.toUpperCase();

  // You must return a Promise when performing
  // asynchronous tasks inside a function
  // such as writing to Firestore.
  // Setting an 'uppercase' field in Firestore document returns a Promise.
  return event.data.ref.set({uppercase}, {merge: true});
});

Питон

@firestore_fn.on_document_created(document="messages/{pushId}")
def makeuppercase(event: firestore_fn.Event[firestore_fn.DocumentSnapshot | None]) -> None:
    """Listens for new documents to be added to /messages. If the document has
    an "original" field, creates an "uppercase" field containg the contents of
    "original" in upper case."""

    # Get the value of "original" if it exists.
    if event.data is None:
        return
    try:
        original = event.data.get("original")
    except KeyError:
        # No "original" field, so do nothing.
        return

    # Set the "uppercase" field.
    print(f"Uppercasing {event.params['pushId']}: {original}")
    upper = original.upper()
    event.data.reference.update({"uppercase": upper})

Функция "make uppercase" выполняется при записи в Cloud Firestore , определяя документ для прослушивания. По соображениям производительности вы должны быть максимально конкретными.

Скобки, например, {documentId} окружают «параметры», подстановочные знаки, которые раскрывают свои сопоставленные данные в обратном вызове. Cloud Firestore запускает обратный вызов всякий раз, когда добавляются новые сообщения.

В Node.js функции, управляемые событиями, такие как события Cloud Firestore являются асинхронными. Функция обратного вызова должна возвращать либо null , либо Object , либо Promise . Если вы ничего не возвращаете, функция истекает по времени, сигнализируя об ошибке, и выполняется повторная попытка. См. Sync, Async и Promises .

Эмулируйте выполнение ваших функций

Firebase Local Emulator Suite позволяет вам создавать и тестировать приложения на локальной машине вместо развертывания в проекте Firebase. Локальное тестирование во время разработки настоятельно рекомендуется, отчасти потому, что оно снижает риск ошибок кодирования, которые могут потенциально повлечь за собой расходы в производственной среде (например, бесконечный цикл).

Для эмуляции ваших функций:

  1. Запустите firebase emulators:start и проверьте вывод URL Emulator Suite UI . По умолчанию это localhost:4000 , но он может быть размещен на другом порту на вашем компьютере. Введите этот URL в браузере, чтобы открыть Emulator Suite UI .

  2. Проверьте вывод команды firebase emulators:start для URL функции HTTP. Он будет выглядеть примерно так http://localhost:5001/MY_PROJECT/us-central1/addMessage , за исключением того, что:

    1. MY_PROJECT будет заменен на идентификатор вашего проекта.
    2. На вашем локальном компьютере порт может быть другим.
  3. Добавьте строку запроса ?text=uppercaseme в конец URL функции. Это должно выглядеть примерно так: http://localhost:5001/MY_PROJECT/us-central1/addMessage?text=uppercaseme . При желании вы можете изменить сообщение "uppercaseme" на пользовательское сообщение.

  4. Создайте новое сообщение, открыв URL-адрес в новой вкладке браузера.

  5. Посмотрите эффекты функций в Emulator Suite UI :

    1. На вкладке «Журналы» вы должны увидеть новые журналы, указывающие на то, что ваши HTTP-функции были выполнены успешно:

      i functions: Beginning execution of "addMessage"

      i functions: Beginning execution of "makeUppercase"

    2. На вкладке Firestore вы увидите документ, содержащий ваше исходное сообщение, а также версию вашего сообщения заглавными буквами (если изначально оно было «uppercaseme», вы увидите «UPPERCASEME»).

Развертывание функций в производственной среде

Как только ваши функции заработают в эмуляторе так, как нужно, вы можете приступить к развертыванию, тестированию и запуску их в производственной среде. Помните, что для развертывания в производственной среде ваш проект должен быть на тарифном плане Blaze . См. цены на Cloud Functions .

Чтобы завершить обучение, разверните свои функции, а затем выполните их.

  1. Выполните эту команду для развертывания ваших функций:

     firebase deploy --only functions
     

    После запуска этой команды Firebase CLI выводит URL для всех конечных точек функции HTTP. В вашем терминале вы должны увидеть строку, подобную следующей:

    Function URL (addMessage): https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage
    

    URL содержит ваш идентификатор проекта, а также регион для функции HTTP. Хотя вам не нужно беспокоиться об этом сейчас, некоторые производственные функции HTTP должны указывать местоположение , чтобы минимизировать сетевую задержку.

    Если вы столкнулись с ошибками доступа, такими как «Невозможно авторизовать доступ к проекту», попробуйте проверить псевдонимы вашего проекта .

  2. Используя URL-адрес, выведенный CLI, добавьте параметр текстового запроса и откройте его в браузере:

    https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage?text=uppercasemetoo
    

    Функция выполняется и перенаправляет браузер в консоль Firebase в местоположении базы данных, где хранится текстовая строка. Это событие записи запускает функцию "make uppercase", которая записывает версию строки в верхнем регистре.

После развертывания и выполнения функций вы можете просматривать журналы в консоли Google Cloud . Если вам нужно удалить функции в разработке или производстве, используйте Firebase CLI.

В производстве вы можете захотеть оптимизировать производительность функции и контролировать затраты, установив минимальное и максимальное количество экземпляров для запуска. См. Управление поведением масштабирования для получения дополнительной информации об этих параметрах времени выполнения.

Следующие шаги

В этой документации вы можете узнать больше о том, как управлять функциями для Cloud Functions , а также о том, как обрабатывать все типы событий, поддерживаемые Cloud Functions .

Чтобы узнать больше о Cloud Functions , вы также можете сделать следующее: