Firebase Cloud Functions — это серверная платформа для выполнения кода в управляемой среде Node.js, которая реагирует на события Firebase, HTTPS-запросы и изменения в облачных сервисах Google. В отличие от традиционного бэкенда, разработчику не нужно настраивать сервер, устанавливать веб-сервер или беспокоиться о масштабировании — каждая функция выполняется в изолированном контейнере и автоматически получает столько ресурсов, сколько нужно. По данным Google Firebase (2026), платформа обрабатывает более 2 миллиардов вызовов функций ежедневно, обеспечивая бессерверную архитектуру для миллионов мобильных приложений.
Главное
Firebase Cloud Functions — это вычислительная платформа, построенная на базе Google Cloud Functions (GCF), адаптированная для экосистемы Firebase. Функции представляют собой обычный JavaScript или TypeScript код, экспортируемый из модуля и регистрируемый на определённый тип события. Когда событие происходит (например, пользователь регистрируется или загружает файл), Firebase Cloud Functions запускает соответствующий код, передавая ему контекст события.
Архитектура Cloud Functions следует принципу единственной ответственности: одна функция обрабатывает один тип события и выполняет одну атомарную операцию. Например, функция sendWelcomeEmail вызывается при создании нового пользователя в Firebase Authentication и отправляет приветственное письмо. Такая изоляция упрощает отладку, тестирование и повторное использование функций в разных проектах.
Каждая функция выполняется в изолированном контейнере с временным жизненным циклом. Максимальное время выполнения по умолчанию составляет 60 секунд (HTTPS-функции — 9 минут). Если функция не укладывается в тайм-аут, запрос завершается ошибкой 500. Для длительных операций используйте Cloud Tasks или Pub/Sub с повторными попытками. Контейнеры могут переиспользоваться для последующих вызовов (keep-alive), что снижает задержку на холодных стартах после первого вызова.
Firebase Cloud Functions поддерживают несколько версий Node.js: 18, 20 и 22 (рекомендуемая для новых проектов). Выбор версии задаётся в engines поле файла package.json. Firebase CLI автоматически настраивает среду выполнения на основе указанной версии. Важно: Firebase Cloud Functions не поддерживают запуск произвольных Docker-контейнеров — среда строго фиксирована Google Cloud Functions.
Для новых проектов рекомендуется Node.js 22, так как она включает последние оптимизации V8, улучшенную работу с модулями ESM и WebSocket-поддержку на уровне платформы. Если проект использует зависимости, собранные для конкретной версии Node (например, нативные модули C++), совместимость нужно проверять отдельно — не все native модули компилируются под GCF среду.
Firebase Cloud Functions — это обёртка над Google Cloud Functions с предустановленным Firebase SDK и интеграцией с Firebase-сервисами. Разработчик пишет код с использованием firebase-functions SDK, который предоставляет типизированные триггеры для всех Firebase-сервисов. Google Cloud Functions — более низкоуровневая платформа, где триггеры настраиваются через Eventarc или Pub/Sub явно.
Ключевое отличие: в Firebase Cloud Functions триггер регистрируется декларативно через вызов functions.firestore.document('path').onWrite(), а в Google Cloud Functions — через конфигурацию Eventarc с фильтрацией по атрибутам события. Firebase Cloud Functions также автоматически поставляется с Admin SDK, инициализированным с правами сервисного аккаунта проекта, что даёт полный доступ ко всем Firebase-сервисам без дополнительной настройки.
Firebase Cloud Functions поддерживает 8 категорий триггеров, каждая из которых соответствует определённому сервису Firebase или Google Cloud. Триггер — это условие, при наступлении которого функция вызывается автоматически. Разработчик не управляет жизненным циклом функции напрямую: Firebase CLI регистрирует триггер в Google Cloud Eventarc, и облачная платформа сама запускает функцию при наступлении события.
Наиболее популярные триггеры — Firestore triggers: onWrite, onCreate, onUpdate, onDelete. Они срабатывают при изменении документов в коллекциях Firestore. Функция получает снапшоты документа до и после изменения, что позволяет сравнивать значения и реагировать только на определённые изменения. Например, при изменении статуса заказа с "pending" на "shipped" можно отправить push-уведомление пользователю.
Authentication triggers (onCreate, onDelete) срабатывают при создании или удалении учётной записи. Используются для инициализации пользовательских данных: создания документа пользователя в Firestore, отправки welcome-email, записи в аналитику. Важно: функция не может отменить создание пользователя — она выполняется после того, как учётная запись уже создана. Для пре-валидации используйте блокирующие функции (Blocking Functions), доступные на платформе Identity Platform.
| Категория триггера | Событие | Пример использования |
|---|---|---|
| Firestore | onWrite, onCreate, onUpdate, onDelete | Обновление счётчика лайков при добавлении |
| Authentication | onCreate, onDelete | Создание профиля пользователя при регистрации |
| Realtime DB | onWrite, onCreate, onUpdate, onDelete | Модерация сообщений в чате |
| Storage | onFinalize, onArchive, onDelete | Генерация thumbnail после загрузки изображения |
| Pub/Sub | onPublish | Периодический запуск (cron) через Cloud Scheduler |
| HTTPS | onRequest | REST API эндпоинт для внешних сервисов |
HTTPS-функции (onRequest) позволяют создавать полноценные REST API эндпоинты, доступные по HTTP. В отличие от событийных триггеров, HTTPS-функции вызываются через URL вида https://{region}-{project}.cloudfunctions.net/{functionName}. Важно правильно настроить CORS, если эндпоинт вызывается из браузера или мобильного приложения. Firebase SDK не включает автоматически CORS-заголовки — их нужно добавлять вручную через middleware.
Для мобильных клиентов (Android, iOS) CORS не требуется, так как нативные HTTP-клиенты не ограничены политикой Cross-Origin. CORS актуален только для веб-запросов. Если ваша HTTPS-функция вызывается как из приложения, так и из веба, добавьте универсальную обработку CORS: res.set('Access-Control-Allow-Origin', '*') для development или список разрешённых доменов для production.
Для периодического выполнения (cron-задачи) используйте комбинацию Cloud Scheduler и Pub/Sub. Cloud Scheduler отправляет сообщение в Pub/Sub топик по расписанию, а Cloud Functions триггер onPublish обрабатывает это сообщение. Firebase CLI не поддерживает прямой синтаксис cron — расписание задаётся через консоль Google Cloud или Terraform в формате unix-cron: 0 3 * * * (каждый день в 3:00).
Пример задач: ежедневная рассылка, очистка устаревших данных, генерация отчётов, синхронизация с внешними API. Важно: Cloud Scheduler — это платный сервис Google Cloud (около $2 в месяц за один job). Каждое срабатывание считается отдельным вызовом функции и тарифицируется по стандартным ценам Cloud Functions.
Разработка Cloud Functions начинается с инициализации проекта через Firebase CLI: firebase init functions. Эта команда создаёт директорию functions/ с шаблоном index.js (или index.ts), файлом package.json и конфигурацией TypeScript (если выбран). После инициализации достаточно написать функцию, экспортировать её из модуля и выполнить firebase deploy --only functions для развёртывания.
Каждая функция регистрируется через вызов метода соответствующего триггера. Пример HTTPS-функции: exports.helloWorld = functions.https.onRequest((req, res) => { res.send("Hello!"); }). Функции Firebase используют асинхронную модель: для событийных триггеров (не HTTPS) функция должна возвращать Promise. Firebase ожидает завершения Promise перед завершением контейнера. Если Promise не возвращён, функция может быть прервана до завершения асинхронных операций.
Локальная разработка ведётся через Firebase Emulator Suite, который включает эмулятор Cloud Functions. Команда firebase emulators:start запускает локальный сервер с функциями, доступный по адресу http://localhost:5001. Эмулятор поддерживает горячую перезагрузку (hot reload) при изменении кода и полностью изолирован от продакшен-среды, что позволяет тестировать функции без риска повлиять на реальные данные.
Зависимости Cloud Functions управляются через package.json. Firebase устанавливает только production-зависимости (dependencies, не devDependencies). Размер пакета функций влияет на время холодного старта: рекомендуется минимизировать количество зависимостей. Для работы с Firebase Admin SDK зависимость firebase-admin уже предустановлена — её не нужно добавлять вручную.
Конфиденциальные данные (API-ключи, токены) не должны храниться в коде функции. Используйте functions.config() для хранения конфигурации: firebase functions:config:set stripe.key="sk_...". Значения зашифрованы и доступны в runtime через functions.config().stripe.key. Для сериализованных конфигураций большого объёма используйте Secret Manager Google Cloud.
Логирование в Cloud Functions осуществляется через console.log, console.warn и console.error. Все логи автоматически собираются в Google Cloud Logging и доступны в консоли Firebase (раздел Functions > Logs). Для структурированного логирования используйте библиотеку winston или pino, которые поддерживают форматирование JSON и уровни логирования.
Обработка ошибок критически важна для надёжности: необработанное исключение в Promise завершает функцию с ошибкой, после чего Firebase автоматически повторяет вызов (retry) с экспоненциальной задержкой. Количество retry настраивается: от 0 до бесконечности. Для событийных триггеров рекомендуется включить retry, чтобы гарантировать обработку каждого события даже при временных сбоях внешних сервисов.
Холодный старт (cold start) — это задержка при первом вызове функции после периода бездействия, когда контейнер с кодом загружается и инициализируется заново. По данным Firebase documentation (2026), холодный старт занимает от 200 мс до 2 секунд в зависимости от размера пакета, количества зависимостей и региона. Для пользовательского интерфейса задержка свыше 1 секунды заметна и может влиять на user experience.
Способы минимизации холодного старта: минимизация зависимостей, использование TypeScript с компиляцией в CommonJS, уменьшение размера пакета функций, установка минимального количества активных инстансов. Firebase Cloud Functions v2 (2nd gen) позволяет задать minInstances — минимальное количество прогретых контейнеров, которые всегда готовы к обработке запросов. За прогрев контейнеров взимается плата за время простоя.
Масштабирование Cloud Functions происходит автоматически: при увеличении количества запросов Firebase создаёт новые контейнеры. По умолчанию максимальное количество параллельных инстансов — 3000 (квота проекта Google Cloud). Каждый инстанс обрабатывает один запрос одновременно. Если функция быстрая (менее 100 мс), один инстанс может обработать до 10 запросов в секунду, что даёт пиковую пропускную способность до 30 000 запросов в секунду на проект.
minInstances — параметр, который резервирует указанное количество контейнеров и держит их прогретыми. Рекомендуется для критических HTTPS-функций, где задержка холодного старта недопустима. Например, для эндпоинта аутентификации задайте minInstances: 1. maxInstances — ограничение на максимальное количество параллельных инстансов, полезное для предотвращения неконтролируемого роста расходов при внезапном всплеске трафика.
Настройка производится в коде: functions.runWith({ minInstances: 1, maxInstances: 10 }). Важно: minInstances увеличивает стоимость, так как контейнер работает непрерывно. Для тестовых проектов minInstances следует отключать. Для production рекомендуется minInstances для всех публичных HTTPS-функций и 0 для событийных триггеров, где задержка в 1 секунду не критична.
Регион развёртывания влияет на задержку до конечных пользователей и стоимость исходящего трафика. Firebase Cloud Functions доступны в 30+ регионах Google Cloud. Для мобильных приложений выбирайте регион, ближайший к вашей целевой аудитории: us-central1 для Америки, europe-west1 для Европы, asia-east2 для Азии. Регион нельзя изменить после деплоя без повторного развёртывания функции.
Смена региона осуществляется через параметр region в коде: functions.region('europe-west1'). Все функции в одном файле могут иметь разные регионы. Для глобальных проектов рекомендуется развернуть функции в нескольких регионах и использовать Cloud Load Balancing для распределения трафика, хотя для большинства мобильных приложений одного региона достаточно при условии правильного выбора.
Рассмотрим практические примеры Cloud Functions на TypeScript. Код использует Firebase Functions SDK v2 (2nd gen) с модульным синтаксисом ES. Примеры включают обработку события создания пользователя, генерацию thumbnail при загрузке изображения и простой HTTPS-эндпоинт для REST API. Все функции асинхронные с возвратом Promise для корректного завершения контейнера.
Перед запуском убедитесь, что Firebase CLI обновлён до версии 13+: npm install -g firebase-tools. Функции v2 требуют тарифного плана Blaze. Инициализация: firebase init functions с выбором TypeScript.
Первый пример — создание документа в Firestore при регистрации нового пользователя. Функция триггерится событием auth.user().onCreate и записывает базовый профиль в коллекцию users/{uid}. Это позволяет гарантировать, что для каждого зарегистрированного пользователя существует документ с необходимыми полями.
import * as functions from "firebase-functions"
import * as admin from "firebase-admin"
admin.initializeApp()
export const createUserProfile = functions.auth
.user()
.onCreate(async (user) => {
const profile = {
email: user.email,
displayName: user.displayName ?? "User",
createdAt: admin.firestore.Timestamp.now(),
role: "free",
avatarUrl: null,
}
await admin.firestore()
.collection("users")
.doc(user.uid)
.set(profile)
console.log(`Profile created for ${user.uid}`)
})
Функция createUserProfile асинхронная — она возвращает Promise, который Firebase ожидает перед завершением. Если запись в Firestore завершится ошибкой (например, из-за отсутствия прав), функция будет повторена автоматически (если включён retry). Поле role со значением "free" позволяет реализовать ограничения бесплатного тарифа прямо в Security Rules Firestore, сравнивая resource.data.role с требуемым уровнем доступа.
Второй пример — триггер Storage для автоматической генерации миниатюры (thumbnail) после загрузки изображения. Функция создаёт уменьшенную копию размером 200x200 пикселей и сохраняет её по пути исходного файла с префиксом thumb_. Для обработки изображений используется библиотека sharp, которая поддерживает все распространённые форматы и работает в среде Node.js без системных зависимостей.
import * as path from "path"
import * as os from "os"
import * as sharp from "sharp"
export const generateThumbnail = functions.storage
.object()
.onFinalize(async (object) => {
if (!object.contentType?.startsWith("image/")) return
const filePath = object.name!
const thumbPath = filePath.replace(
/(\.\w+)$/, "_thumb$1"
)
const bucket = admin.storage().bucket()
const tempDir = os.tmpdir()
const tempFile = path.join(tempDir, path.basename(filePath))
await bucket.file(filePath).download({ destination: tempFile })
await sharp(tempFile)
.resize(200, 200, { fit: "cover" })
.toFile(tempFile.replace(/(\.\w+)$/, "_thumb$1"))
await bucket.upload(tempFile.replace(
/(\.\w+)$/, "_thumb$1"
), { destination: thumbPath })
})
Функция generateThumbnail проверяет Content-Type объекта и игнорирует не-изображения, что экономит ресурсы. Для работы с sharp зависимость должна быть добавлена в package.json. Thumbnail создаётся с параметром fit: "cover", который обрезает изображение по центру до квадрата 200x200 пикселей. После создания thumbnail загружается обратно в тот же бакет с модифицированным именем.
Третий пример — HTTPS-функция, реализующая REST API эндпоинт для проверки статуса сервера. Функция принимает GET-запрос и возвращает JSON с информацией о состоянии Firebase сервисов, подключённых к проекту. Эндпоинт полезен для мониторинга и внешних систем, которым нужно проверить доступность бэкенда перед отправкой данных.
import * as express from "express"
const app = express.Router()
app.get("/status", async (req, res) => {
try {
const db = admin.firestore()
await db.collection("_health").doc("check").get()
res.json({ status: "ok", timestamp: Date.now() })
} catch (error) {
res.status(503).json({ status: "error", message: error })
}
})
export const api = functions.https.onRequest(app)
Функция api использует express Router для маршрутизации, что удобно при создании нескольких эндпоинтов в одной функции. Health check записывается в Firestore в коллекцию _health, что позволяет одновременно проверить и доступность Firestore. Для production рекомендуется добавить аутентификацию запроса через API-ключ или Firebase Auth токен, чтобы предотвратить злоупотребление публичным эндпоинтом.
Cloud Functions чаще всего применяются для задач, которые невозможно или нежелательно выполнять на клиенте: отправка push-уведомлений, генерация превью загруженных изображений, интеграция с внешними платежными системами, модерация контента, синхронизация данных между Firebase и сторонними сервисами. Бессерверная модель делает эти задачи экономичными: плата взимается только за фактическое время выполнения кода.
Интеграция с платежными системами — типовой сценарий для приложений с in-app покупками. Cloud Functions получает вебхук от платежного провайдера (Stripe, PayPal), проверяет подпись запроса, обновляет статус подписки в Firestore и отправляет пользователю подтверждение. Весь код выполняется на сервере без риска подмены данных на клиенте. По данным Stripe documentation (2026), обработка вебхука занимает менее 500 мс.
Умная модерация контента использует Cloud Function триггер Storage для автоматической проверки загруженных изображений через Google Cloud Vision API. Функция отправляет изображение в Vision API для детекции небезопасного контента (насилие, контент для взрослых) и, если порог превышен, удаляет файл и уведомляет администратора. Этот сценарий критически важен для UGC-приложений с пользовательскими галереями.
Агрегация данных — Cloud Functions как замена Firebase Realtime Database counters. Вместо чтения и записи счётчика на клиенте (что приводит к race conditions), используйте Firestore триггер onWrite для атомарного обновления агрегированных полей. Например, функция подсчитывает количество лайков поста при каждом добавлении или удалении документа в подколлекции /posts/{postId}/likes/{userId} и обновляет поле likesCount в родительском документе.
Часто задаваемые вопросы
Максимальное время выполнения зависит от типа: HTTPS-функции — 9 минут, событийные триггеры — 60 секунд (v2: до 60 минут). Для длительных операций используйте Cloud Tasks или Pub/Sub с асинхронной обработкой. Тайм-аут настраивается в коде через runWith({ timeoutSeconds: 120 }).
Используйте Firebase Emulator Suite: firebase emulators:start --only functions. Эмулятор запускает функции локально на порту 5001 с поддержкой горячей перезагрузки. Для триггеров Firestore и Auth эмулятор подменяет реальные сервисы, позволяя тестировать сценарии без риска для боевых данных.
2nd gen использует Google Cloud Run и Eventarc, предоставляя более длительный тайм-аут (до 60 минут), конкурентную обработку запросов одним инстансом и улучшенную интеграцию с Google Cloud сервисами. 1st gen использует Google Cloud Functions и ограничен 60 секундами для событийных функций. Firebase рекомендует новые проекты начинать с 2nd gen.
Firebase Cloud Functions официально поддерживает только Node.js (JavaScript и TypeScript). Для Python используйте Google Cloud Functions напрямую с Firebase Admin SDK для Python. Firebase Admin SDK Python поддерживает все операции, за исключением некоторых Firebase-специфичных триггеров, которые доступны только через Node.js.
Для аутентифицированного доступа проверяйте Firebase ID токен в заголовке Authorization: admin.auth().verifyIdToken(token). Для сервер-серверной интеграции используйте Firebase Admin SDK с сервисным аккаунтом или API-ключи. Для публичных эндпоинтов с ограничением по скорости используйте rate limiting через Cloud Armor или middleware.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также