Управление функциями (1-го поколения)

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

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

Для развертывания функций выполните следующую команду Firebase CLI:

firebase deploy --only functions

По умолчанию Firebase CLI развертывает все функции из вашего исходного кода одновременно. Если ваш проект содержит более 5 функций, мы рекомендуем использовать флаг --only с указанием конкретных имен функций, чтобы развернуть только те функции, которые вы отредактировали. Развертывание определенных функций таким образом ускоряет процесс развертывания и помогает избежать превышения квот на развертывание. Например:

firebase deploy --only functions:addMessage,functions:makeUppercase

При развертывании большого количества функций вы можете превысить стандартную квоту и получить сообщения об ошибках HTTP 429 или 500. Для решения этой проблемы развертывайте функции группами по 10 или менее функций.

Полный список доступных команд см. в справочнике Firebase CLI .

По умолчанию Firebase CLI ищет исходный код в папке functions/ . При желании вы можете организовать функции в кодовые базы или несколько наборов файлов.

Удаление функций

Удалить ранее развернутые функции можно следующими способами:

  • явно в Firebase CLI с помощью functions:delete
  • явно в консоли Google Cloud .
  • это подразумевается путем удаления функции из исходного кода перед развертыванием.

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

Явное удаление функций в Firebase CLI поддерживает несколько аргументов, а также группы функций и позволяет указать функцию, выполняющуюся в определенном регионе. Кроме того, можно отключить запрос подтверждения.

# Delete all functions that match the specified name in all regions.
firebase functions:delete myFunction
# Delete a specified function running in a specific region.
firebase functions:delete myFunction --region us-east-1
# Delete more than one function
firebase functions:delete myFunction myOtherFunction
# Delete a specified functions group.
firebase functions:delete groupA
# Bypass the confirmation prompt.
firebase functions:delete myFunction --force

При использовании неявного удаления функций firebase deploy анализирует исходный код и удаляет из производственной среды все функции, которые были удалены из файла.

Изменить имя функции, регион или триггер

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

Переименовать функцию

Чтобы переименовать функцию, создайте новую переименованную версию функции в исходном коде, а затем выполните две отдельные команды развертывания. Первая команда развернет функцию с новым именем, а вторая удалит ранее развернутую версию. Например, если у вас есть функция Node.js с именем webhook , которую вы хотите изменить на webhookNew , измените код следующим образом:

// before
const functions = require('firebase-functions/v1');

exports.webhook = functions.https.onRequest((req, res) => {
    res.send("Hello");
});

// after
const functions = require('firebase-functions/v1');

exports.webhookNew = functions.https.onRequest((req, res) => {
    res.send("Hello");
});

Затем выполните следующие команды для развертывания новой функции:

# Deploy new function called webhookNew
firebase deploy --only functions:webhookNew

# Wait until deployment is done; now both webhookNew and webhook are running

# Delete webhook
firebase functions:delete webhook

Изменить область или области функции

Если вы изменяете указанные регионы для функции, обрабатывающей производственный трафик, вы можете предотвратить потерю событий, выполнив следующие действия в указанном порядке:

  1. Переименуйте функцию и измените ее область или области по своему усмотрению.
  2. Разверните переименованную функцию, в результате чего один и тот же код будет временно выполняться в обоих наборах регионов.
  3. Удалите предыдущую функцию.

Например, если у вас есть функция с именем webhook , которая в настоящее время находится в регионе функций по умолчанию us-central1 , и вы хотите перенести ее в asia-northeast1 , вам сначала нужно изменить исходный код, переименовать функцию и изменить регион.

// before
const functions = require('firebase-functions/v1');

exports.webhook = functions
    .https.onRequest((req, res) => {
            res.send("Hello");
    });

// after
const functions = require('firebase-functions/v1');

exports.webhookAsia = functions
    .region('asia-northeast1')
    .https.onRequest((req, res) => {
            res.send("Hello");
    });

Затем выполните развертывание, запустив команду:

firebase deploy --only functions:webhookAsia

Сейчас работают две идентичные функции: webhook запущен в us-central1 , а webhookAsia — в asia-northeast1 .

Затем удалите webhook :

firebase functions:delete webhook

Теперь существует только одна функция — webhookAsia , которая работает в регионе asia-northeast1 .

Изменение типа триггера функции

В процессе разработки развертывания Cloud Functions for Firebase вам может потребоваться изменить тип триггера функции по различным причинам. Например, вы можете захотеть перейти от одного типа событий Firebase Realtime Database или Cloud Firestore к другому.

Изменить тип события функции, просто изменив исходный код и запустив firebase deploy , невозможно. Во избежание ошибок измените тип триггера функции следующим образом:

  1. Измените исходный код, добавив новую функцию с желаемым типом триггера.
  2. Разверните функцию, в результате чего временно будут запущены как старая, так и новая функции.
  3. Явно удалите старую функцию из рабочей среды с помощью Firebase CLI.

Например, если у вас есть функция Node.js с именем objectChanged , имеющая устаревший тип события onChange , и вы хотите изменить его на onFinalize , сначала переименуйте функцию и отредактируйте ее, добавив тип события onFinalize .

// before
const functions = require('firebase-functions/v1');

exports.objectChanged = functions.storage.object().onChange((object) => {
    return console.log('File name is: ', object.name);
});

// after
const functions = require('firebase-functions/v1');

exports.objectFinalized = functions.storage.object().onFinalize((object) => {
    return console.log('File name is: ', object.name);
});

Затем выполните следующие команды, чтобы сначала создать новую функцию, а затем удалить старую:

# Create new function objectFinalized
firebase deploy --only functions:objectFinalized

# Wait until deployment is done; now both objectChanged and objectFinalized are running

# Delete objectChanged
firebase functions:delete objectChanged

Задайте параметры выполнения

Cloud Functions for Firebase позволяет выбирать параметры среды выполнения, такие как версия среды выполнения Node.js, время ожидания для каждой функции, выделение памяти, а также минимальное/максимальное количество экземпляров функций.

В качестве оптимальной практики эти параметры (за исключением версии Node.js) следует задавать в объекте конфигурации внутри кода функции. Объект RuntimeOptions является источником достоверной информации о параметрах выполнения вашей функции и будет переопределять параметры, установленные любым другим способом (например, через консоль Google Cloud или CLI gcloud).

Если ваш рабочий процесс разработки включает ручную настройку параметров среды выполнения через консоль Google Cloud или CLI gcloud, и вы не хотите, чтобы эти значения перезаписывались при каждом развертывании, установите параметр preserveExternalChanges в true . При установке этого параметра в true Firebase объединит параметры среды выполнения, заданные в вашем коде, с настройками текущей развернутой версии вашей функции со следующим приоритетом:

  1. Параметр задается в коде функции: переопределять внешние изменения.
  2. В коде функций параметр установлен в значение RESET_VALUE : он переопределяет внешние изменения значением по умолчанию.
  3. Параметр задается не в коде функции, а в текущей развернутой функции: используйте параметр, указанный в развернутой функции.

В большинстве случаев использование параметра preserveExternalChanges: true не рекомендуется, поскольку ваш код больше не будет являться полным источником достоверной информации о параметрах выполнения ваших функций. Если вы все же используете его, проверьте консоль Google Cloud или воспользуйтесь интерфейсом командной строки gcloud, чтобы просмотреть полную конфигурацию функции.

Установить версию Node.js

Firebase SDK для Cloud Functions позволяет выбирать среду выполнения Node.js. Вы можете выбрать запуск всех функций в проекте исключительно в среде выполнения, соответствующей одной из поддерживаемых версий Node.js:

  • Node.js 22
  • Node.js 20
  • Node.js 18 (устарело)

Важную информацию о текущей поддержке этих версий Node.js см. в графике технической поддержки.

Чтобы задать версию Node.js:

Версию можно задать в поле engines файла package.json , созданного в каталоге functions/ во время инициализации. Например, чтобы использовать только версию 20, отредактируйте следующую строку в package.json :

  "engines": {"node": "22"}

Если вы используете менеджер пакетов Yarn или у вас есть другие специфические требования к полю engines , вы можете указать среду выполнения для Firebase SDK for Cloud Functions в файле firebase.json :

  {
    "functions": {
      "runtime": "nodejs22"
    }
  }

Интерфейс командной строки использует значение, заданное в файле firebase.json вместо любого значения или диапазона, которые вы зададите отдельно в package.json .

Обновите среду выполнения Node.js.

Чтобы обновить среду выполнения Node.js:

  1. Убедитесь, что ваш проект подключен к тарифному плану Blaze .
  2. Убедитесь, что вы используете Firebase CLI версии 11.18.0 или более поздней.
  3. Измените значение параметра engines в файле package.json , который был создан в каталоге functions/ во время инициализации. Например, если вы обновляетесь с версии 16 до версии 18, запись должна выглядеть так: "engines": {"node": "18"}
  4. При желании вы можете протестировать свои изменения с помощью Firebase Local Emulator Suite .
  5. Переразверните все функции.

Выберите систему модулей Node.js

В Node.js по умолчанию используется модульная система CommonJS (CJS), но текущие версии Node.js также поддерживают модули ECMAScript (ESM). Cloud Functions поддерживает оба варианта.

По умолчанию ваши функции используют CommonJS. Это означает, что импорт и экспорт выглядят следующим образом:

const functions = require("firebase-functions/v1");

exports.helloWorld = functions.https.onRequest(async (req, res) => res.send("Hello from Firebase!"));

Чтобы использовать ESM, укажите поле "type": "module" в файле package.json :

  {
   ...
   "type": "module",
   ...
  }

После установки этих параметров используйте синтаксис import и export ESM:

import functions from "firebase-functions/v1";

export const helloWorld = functions.https.onRequest(async (req, res) => res.send("Hello from Firebase!"));

Обе системы модулей полностью поддерживаются. Вы можете выбрать ту, которая лучше всего подходит для вашего проекта. Подробнее см. в документации Node.js по модулям .

Управление масштабированием поведения

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

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

Сократите количество холодных запусков.

Чтобы задать минимальное количество экземпляров для функции в исходном коде, используйте метод runWith . Этот метод принимает объект JSON, соответствующий интерфейсу RuntimeOptions , который определяет значение для minInstances . Например, эта функция устанавливает минимум 5 экземпляров для поддержания состояния "в режиме ожидания":

exports.getAutocompleteResponse = functions
    .runWith({
      // Keep 5 instances warm for this latency-critical function
      minInstances: 5,
    })
    .https.onCall((data, context) => {
      // Autocomplete a user's search term
    });

Вот несколько моментов, которые следует учитывать при установке значения для minInstances :

  • Если Cloud Functions for Firebase масштабирует ваше приложение сверх значения параметра minInstances , каждый экземпляр, превышающий этот порог, будет запускаться с холодным стартом.
  • Холодные запуски оказывают наиболее сильное воздействие на приложения с резкими скачками трафика. Если ваше приложение имеет резкие скачки трафика, и вы установите значение minInstances достаточно высоким, чтобы количество холодных запусков уменьшалось при каждом увеличении трафика, вы увидите значительное снижение задержки. Для приложений с постоянным трафиком холодные запуски вряд ли окажут существенное влияние на производительность.
  • Установка минимального количества экземпляров может быть целесообразна в производственных средах, но обычно ее следует избегать в тестовых средах. Чтобы масштабировать тестовый проект до нуля, но при этом уменьшить количество холодных запусков в производственном проекте, вы можете установить minInstances на основе переменной среды FIREBASE_CONFIG :

    // Get Firebase project id from `FIREBASE_CONFIG` environment variable
    const envProjectId = JSON.parse(process.env.FIREBASE_CONFIG).projectId;
    
    exports.renderProfilePage = functions
        .runWith({
          // Keep 5 instances warm for this latency-critical function
          // in production only. Default to 0 for test projects.
          minInstances: envProjectId === "my-production-project" ? 5 : 0,
        })
        .https.onRequest((req, res) => {
          // render some html
        });
    

Ограничить максимальное количество экземпляров функции.

Для установки максимального количества экземпляров в исходном коде функции используйте метод runWith . Этот метод принимает объект JSON, соответствующий интерфейсу RuntimeOptions , который определяет значения для maxInstances . Например, эта функция устанавливает ограничение в 100 экземпляров, чтобы не перегружать гипотетическую устаревшую базу данных:

exports.mirrorOrdersToLegacyDatabase = functions
    .runWith({
      // Legacy database only supports 100 simultaneous connections
      maxInstances: 100,
    })
    .firestore.document("orders/{orderId}")
    .onWrite((change, context) => {
      // Connect to legacy database
    });

Если масштаб HTTP-функции достигает предела maxInstances , новые запросы ставятся в очередь на 30 секунд, а затем отклоняются с кодом ответа 429 Too Many Requests если к этому времени не остается доступных экземпляров.

Чтобы узнать больше о лучших практиках использования настроек максимального количества экземпляров, ознакомьтесь с этими рекомендациями по использованию maxInstances .

Настроить служебный аккаунт

Учетная запись службы по умолчанию для функций первого поколения, PROJECT_ID @ appspot.gserviceaccount.com (называемая учетной записью службы App Engine по умолчанию ), обладает широким набором разрешений, позволяющих взаимодействовать с другими сервисами Firebase и Google Cloud.

Возможно, вам потребуется переопределить учетную запись службы по умолчанию и ограничить функцию только необходимыми ресурсами. Это можно сделать, создав пользовательскую учетную запись службы и назначив ее соответствующей функции с помощью метода ` .runWith() . Этот метод принимает объект с параметрами конфигурации, включая свойство ` serviceAccount .

const functions = require("firebase-functions/v1");

exports.helloWorld = functions
    .runWith({
        // This function doesn't access other Firebase project resources, so it uses a limited service account.
        serviceAccount:
            "my-limited-access-sa@", // or prefer the full form: "my-limited-access-sa@my-project.iam.gserviceaccount.com"
    })
    .https.onRequest((request, response) => {
        response.send("Hello from Firebase!");
    });

Установить тайм-аут и выделить память.

В некоторых случаях ваши функции могут предъявлять особые требования к длительному времени ожидания или большому объему выделяемой памяти. Вы можете задать эти значения либо в консоли Google Cloud, либо в исходном коде функции (только в Firebase).

Для задания выделения памяти и таймаута в исходном коде функций используйте параметр runWith , представленный в Firebase SDK для Cloud Functions 2.0.0. Этот параметр среды выполнения принимает объект JSON, соответствующий интерфейсу RuntimeOptions , который определяет значения для timeoutSeconds и memory . Например, эта функция хранения использует 1 ГБ памяти и завершается по истечении 300 секунд:

exports.convertLargeFile = functions
    .runWith({
      // Ensure the function has enough memory and time
      // to process large files
      timeoutSeconds: 300,
      memory: "1GB",
    })
    .storage.object()
    .onFinalize((object) => {
      // Do some complicated things that take a lot of memory and time
    });

Максимальное значение параметра timeoutSeconds составляет 540 , или 9 минут. Объем памяти, выделяемый функции, соответствует процессору, выделенному для этой функции, как подробно описано в этом списке допустимых значений memory :

  • 128MB — 200 МГц
  • 256MB — 400 МГц
  • 512MB — 800 МГц
  • 1GB — 1,4 ГГц
  • 2GB — 2,4 ГГц
  • 4GB — 4,8 ГГц
  • 8GB — 4,8 ГГц

Чтобы настроить выделение памяти и тайм-аут в консоли Google Cloud :

  1. В консоли Google Cloud выберите Cloud Functions в меню слева.
  2. Выберите функцию, щелкнув по ее названию в списке функций.
  3. Нажмите на значок «Редактировать» в верхнем меню.
  4. Выберите выделение памяти из выпадающего меню с заголовком «Выделенная память» .
  5. Нажмите «Подробнее» , чтобы отобразить расширенные параметры, и введите число секунд в текстовое поле «Тайм-аут» .
  6. Нажмите «Сохранить» , чтобы обновить функцию.