فراخوانی توابع ازطریق درخواست‌های HTTP

می‌توانید ازطریق درخواست HTTP با گرداننده درخواست، تابعی را راه‌اندازی کنید. این به شما امکان می‌دهد تا ازطریق روش‌های HTTP پشتیبانی‌شده زیر، تابعی را فراخوانی کنید: GET، POST، PUT، DELETE، و OPTIONS.

این راهنما فرض می‌کند که شما کارهای راه‌اندازی شرح داده‌شده در راهنمای شروع به کار برای Node.js و Python، یا کارهای راه‌اندازی برای کیت توسعه نرم‌افزار Dart آزمایشی را تکمیل کرده‌اید.

گزینه‌های HTTP اضافی

گزینه شرح
region توابع HTTP ممکن است آرایه‌ای از مناطق و همچنین یک منطقه را مشخص کنند. وقتی چند منطقه مشخص شده باشد، برای هر منطقه یک نمونه تابع جداگانه مستقر خواهد شد.
‫timeoutSeconds (timeout_sec برای Python) توابع HTTP ممکن است زمان استراحتی تا یک ساعت را مشخص کنند.
cors توابع HTTP ممکن است خط‌مشی‌های CORS را مشخص کنند. می‌توانید این را روی true تنظیم کنید تا همه مبدأها مجاز شوند یا string، regex، یا array را برای مشخص کردن مبدأهای مجاز تنظیم کنید. اگر به‌طور صریح تنظیم نشده باشد، به‌طور پیش‌فرض روی نادرست/بدون خط‌مشی‌های CORS قرار می‌گیرد.

پیکربندی CORS (هم‌رسانی منبع میان‌مبدئی)

از گزینه cors برای کنترل اینکه کدام مبدأها می‌توانند به تابع شما دسترسی داشته باشند استفاده کنید. به‌طور پیش‌فرض، CORS برای توابع HTTP پیکربندی نشده است، یعنی هر درخواست میان‌مبدئی به تابع شما منجر به این خطا می‌شود:

request has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

همچنین می‌توانید با تنظیم گزینه cors روی false برای تابع خود، CORS را به‌طور صریح غیرفعال کنید.

برای مجاز کردن برخی‌از درخواست‌های میان‌مبدئی، اما نه همه آن‌ها، می‌توانید فهرستی از دامنه‌های خاص یا عبارت‌های باقاعده را که باید مجاز شوند ارسال کنید. برای مثال، اگر مالک دامنه‌های 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!");
  }
);

پایتون

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!'),
    );
  });
}

اگر تابع شما باید به‌طور عمومی دردسترس باشد، برای مثال اگر درحال ارائه یک میانای برنامه‌سازی کاربردی یا وب‌سایت عمومی است، خط‌مشی cors را روی true تنظیم کنید.

راه‌اندازی تابع با درخواست اچ‌تی‌تی‌پی

از گرداننده درخواست برای پلاتفرم خود استفاده کنید تا تابعی ایجاد کنید که رویدادهای HTTP را مدیریت کند. نمونه‌های این بخش براساس نمونه «سرور زمان» است که وقتی درخواست اچ‌تی‌تی‌پی GET به نقطه پایانی توابع ارسال می‌کنید، راه‌اندازی می‌شود. تابع نمونه زمان فعلی سرور را بازیابی می‌کند، زمان را به‌صورت مشخص‌شده در پارامتر پُرسمان نشانی وب قالب‌بندی می‌کند، و نتیجه را در پاسخ HTTP ارسال می‌کند.

استفاده از اشیای درخواست و پاسخ

شیء درخواست به شما امکان می‌دهد به ویژگی‌های درخواست HTTP ارسال‌شده توسط کارخواه دسترسی داشته باشید، و شیء پاسخ به شما امکان می‌دهد پاسخی به کارخواه ارسال کنید.

Node.js

exports.date = onRequest(
    {timeoutSeconds: 1200, region: ["us-west1", "us-east1"]},
    (req, res) => {
// ...
});

پایتون

@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);

پایتون

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، می‌توانید آن را ازطریق نشانی وب منحصربه‌فرد خودش فراخوانی کنید. از نشانی وب دقیقی که پس‌از استقرار از CLI خروجی گرفته شده است استفاده کنید.

برای مثال، نشانی وب برای فراخوانی date() به‌این‌صورت است:

https://us-central1-<project-id>.cloudfunctions.net/date

با مسیریابی برنامه Express و Flask، نام تابع به‌عنوان پیشوند به مسیرهای نشانی وب در برنامه‌ای که تعریف می‌کنید اضافه می‌شود.

خواندن مقادیر از درخواست

در مثال تابع date()، تابع هم پارامتر نشانی وب و هم بدنه را برای مقدار format آزمایش می‌کند تا قالب تاریخ/زمان را برای استفاده تنظیم کند:

Node.js

let format = req.query.format;
format = req.body.format;

پایتون

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');
}

فسخ کردن توابع اچ‌تی‌تی‌پی

پس‌از بازیابی و قالب‌بندی زمان سرور، تابع date() با ارسال نتیجه در پاسخ HTTP به پایان می‌رسد:

Node.js

همیشه تابع HTTP را با send()،‏ redirect()، یا end() پایان دهید. درغیراین‌صورت، ممکن است تابع شما همچنان اجرا شود و سیستم آن را به‌اجبار متوقف کند. همچنین ببینید همگام‌سازی، غیرهمگام‌سازی، و وعده‌ها.

const formattedDate = moment().format(`${format}`);
logger.log("Sending formatted date:", formattedDate);
res.status(200).send(formattedDate);

پایتون

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

می‌توانید تابع HTTP را به Firebase Hosting متصل کنید. درخواست‌های سایت Firebase Hosting شما می‌تواند به عملکردهای خاص HTTP پروکسی شود. این کار همچنین به شما امکان می‌دهد از دامنه سفارشی خودتان با تابع HTTP استفاده کنید. درباره اتصال Cloud Functions به Firebase Hosting بیشتر بدانید.