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


Чтобы начать работу с 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:

    Либо выберите существующую учетную запись Google Analytics , либо создайте новую учетную запись.

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

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

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

Настройте свою среду и интерфейс командной строки Firebase

Node.js

Для написания функций вам понадобится среда Node.js , а для развертывания функций в среде выполнения Cloud Functions вам понадобится интерфейс командной строки Firebase . Для установки 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 .
  2. Перейдите в каталог проекта Firebase.
  3. Запустите firebase init firestore . В этом руководстве вы можете принять значения по умолчанию при появлении запроса на правила Firestore и индексные файлы. Если вы еще не использовали Cloud Firestore в этом проекте, вам также необходимо выбрать режим запуска и местоположение для Firestore, как описано в разделе «Начало работы с Cloud Firestore .
  4. Запустите firebase init functions . Интерфейс командной строки предложит вам выбрать существующую кодовую базу или инициализировать и назвать новую. Когда вы только начинаете, достаточно одной базы кода в расположении по умолчанию; позже, по мере расширения вашей реализации, вы можете захотеть организовать функции в базах кода .
  5. CLI предоставляет следующие возможности языковой поддержки:

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

    Для этого руководства выберите JavaScript или Python . Информацию о разработке на TypeScript см. в разделе «Написание функций с помощью 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 автоматически устанавливает модули Firebase Admin SDK и Firebase SDK для Cloud Functions при инициализации проекта. Дополнительные сведения о добавлении сторонних библиотек в проект см. в разделе «Обработка зависимостей» .

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

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

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 «добавить сообщение» передает текстовое значение конечной точке 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 . Если вы ничего не возвращаете, время ожидания функции истекает, сигнализируя об ошибке, и она повторяется. См . раздел «Синхронизация, асинхронность и обещания» .

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

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 . При желании вы можете изменить сообщение «заглавная буква» на собственное сообщение.

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

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

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

      i functions: Beginning execution of "addMessage"

      i functions: Beginning execution of "makeUppercase"

    2. На вкладке Firestore вы должны увидеть документ, содержащий ваше исходное сообщение, а также версию вашего сообщения, написанную заглавными буквами (если изначально оно было «ПРОПИСНЫМИ», вы увидите «ПРОПИСНУЮ»).

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

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

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

  1. Запустите эту команду, чтобы развернуть ваши функции:

     firebase deploy --only functions
     

    После запуска этой команды интерфейс командной строки Firebase выводит 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 .

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

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

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

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