Вы можете запустить функцию через HTTP-запрос с помощью обработчика запросов. Это позволяет вызывать функцию с помощью следующих поддерживаемых методов HTTP: GET, POST, PUT, DELETE и OPTIONS.
В этом руководстве предполагается, что вы выполнили задачи по настройке, описанные в руководстве по началу работы с Node.js и Python или в руководстве по настройке экспериментального Dart SDK.
Дополнительные параметры HTTP
| Параметр | Описание |
|---|---|
region |
Для HTTP-функций можно указать как один регион, так и массив регионов. Если указано несколько регионов, для каждого из них будет развернут отдельный экземпляр функции. |
timeoutSeconds (timeout_sec для Python) |
Для функций HTTP можно указать время ожидания до одного часа. |
cors |
В HTTP-функциях можно указать правила CORS. Вы можете задать значение true, чтобы разрешить все источники, или string, regex или array, чтобы указать разрешенные источники. Если значение не задано, по умолчанию используется false/no CORS policies. |
Настройка CORS (совместное использование ресурсов из разных источников)
Используйте параметр cors, чтобы указать, какие источники могут получить доступ к вашей функции. По умолчанию для HTTP-функций не настроена технология CORS. Это значит, что любой междоменный запрос к функции приведет к следующей ошибке:
request has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Вы также можете явно отключить CORS, задав для параметра cors значение false.
Чтобы разрешить только некоторые междоменные запросы, можно передать список определенных доменов или регулярных выражений, которые должны быть разрешены. Например, если вы владеете доменами firebase.com и flutter.com, а у домена firebase.com может быть много субдоменов, то вы можете задать параметр cors следующим образом:
Node.js
const { onRequest } = require("firebase-functions/v2/https");
exports.sayHello = onRequest(
{ cors: [/firebase\.com$/, "https://flutter.com"] },
(req, res) => {
res.status(200).send("Hello world!");
}
);
Python
from firebase_functions import https_fn, options
@https_fn.on_request(
cors=options.CorsOptions(
cors_origins=[r"firebase\.com$", r"https://flutter\.com"],
cors_methods=["get", "post"],
)
)
def say_hello(req: https_fn.Request) -> https_fn.Response:
return https_fn.Response("Hello world!")
Dart (экспериментальная функция)
import 'package:firebase_functions/firebase_functions.dart';
void main() {
runFunctions((firebase) {
firebase.https.onRequest(
name: 'sayHello',
options: const HttpsOptions(
cors: Cors([RegExp(r'^https:\/\/firebase\.com$'), 'https://flutter.com']),
),
(request) async => Response(200, body: 'Hello world!'),
);
});
}
Если функция должна быть общедоступной, например если она обслуживает общедоступный API или сайт, задайте для правила cors значение true.
Как запустить функцию с помощью HTTP-запроса
Используйте обработчик запросов для своей платформы, чтобы создать функцию, которая обрабатывает события HTTP. Примеры в этом разделе основаны на примере "сервера времени", который запускается, когда вы отправляете HTTP-запрос GET конечной точке функции. Пример функции получает текущее время сервера, форматирует его в соответствии с параметром запроса URL и отправляет результат в HTTP-ответе.
Как использовать объекты запросов и ответов
Объект запроса предоставляет доступ к свойствам HTTP-запроса, отправленного клиентом, а объект ответа позволяет отправить ответ клиенту.
Node.js
exports.date = onRequest( {timeoutSeconds: 1200, region: ["us-west1", "us-east1"]}, (req, res) => { // ... });
Python
@https_fn.on_request(cors=options.CorsOptions(cors_origins="*", cors_methods=["get", "post"]))
def date(req: https_fn.Request) -> https_fn.Response:
"""Get the server's local date and time."""
Dart (экспериментальная функция)
void main() {
runFunctions((firebase) {
firebase.https.onRequest(name: 'date', (request) async {
Использование существующих приложений Express или Flask
Используя приложение в качестве аргумента для обработчика запросов, вы можете передать полное приложение в функцию HTTP:
Node.js
const { onRequest } = require('firebase-functions/v2/https');
const express = require('express');
const app = express();
// Add middleware to authenticate requests
app.use(myMiddleware);
// build multiple CRUD interfaces:
app.get('/:id', (req, res) => res.send(Widgets.getById(req.params.id)));
app.post('/', (req, res) => res.send(Widgets.create()));
app.put('/:id', (req, res) => res.send(Widgets.update(req.params.id, req.body)));
app.delete('/:id', (req, res) => res.send(Widgets.delete(req.params.id)));
app.get('/', (req, res) => res.send(Widgets.list()));
// Expose Express API as a single Cloud Function:
exports.widgets = onRequest(app);
Python
from firebase_admin import initialize_app, db
from firebase_functions import https_fn
import flask
initialize_app()
app = flask.Flask(__name__)
# Build multiple CRUD interfaces:
@app.get("/widgets")
@app.get("/widgets/<id>")
def get_widget(id=None):
if id is not None:
return db.reference(f"/widgets/{id}").get()
else:
return db.reference("/widgets").get()
@app.post("/widgets")
def add_widget():
new_widget = flask.request.get_data(as_text=True)
db.reference("/widgets").push(new_widget)
return flask.Response(status=201, response="Added widget")
# Expose Flask app as a single Cloud Function:
@https_fn.on_request()
def httpsflaskexample(req: https_fn.Request) -> https_fn.Response:
with app.request_context(req.environ):
return app.full_dispatch_request()
Как вызвать HTTP-функцию
После развертывания HTTP-функции ее можно вызвать по уникальному URL. Используйте точный URL, полученный из CLI после развертывания.
Например, URL для вызова date() выглядит так:
https://us-central1-<project-id>.cloudfunctions.net/date
При маршрутизации приложений Express и Flask название функции добавляется в качестве префикса к путям URL в определяемом вами приложении.
Считывание значений из запроса
В примере функции date() проверяется, есть ли значение format в параметре URL и теле запроса, чтобы задать формат даты и времени:
Node.js
let format = req.query.format; format = req.body.format;
Python
format = req.args["format"] if "format" in req.args else None
Dart (экспериментальная функция)
var format = request.url.queryParameters['format'];
final bodyString = await request.readAsString();
try {
if (bodyString.isNotEmpty) {
final body = jsonDecode(bodyString) as Map<String, dynamic>;
format = body['format'] as String?;
}
} catch (e) {
return Response.badRequest(body: 'invalid JSON');
}
Завершение HTTP-функций
После получения и форматирования времени сервера функция date() отправляет результат в HTTP-ответе:
Node.js
Всегда завершайте HTTP-функцию с помощью send(), redirect() или end(). В противном случае функция может продолжить работу и будет принудительно завершена системой. Также ознакомьтесь со статьей Синхронность, асинхронность и промисы.
const formattedDate = moment().format(`${format}`); logger.log("Sending formatted date:", formattedDate); res.status(200).send(formattedDate);
Python
formatted_date = datetime.now().strftime(format)
print(f"Sending Formatted date: {formatted_date}")
return https_fn.Response(formatted_date)
Dart (экспериментальная функция)
final formattedDate = DateFormat(format).format(DateTime.now());
print('Sending formatted date: $formattedDate');
return Response.ok(formattedDate);
Интеграция с Firebase Hosting
Вы можете подключить функцию HTTP к Firebase Hosting. Запросы на сайте Firebase Hosting можно перенаправлять на определенные функции HTTP. Это также позволяет использовать собственный домен с функцией HTTP. Подробнее о том, как подключить Cloud Functions к Firebase Hosting…