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

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

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

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

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

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

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

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

از مدیریت‌کننده درخواست برای پلاتفرم خود استفاده کنید تا تابعی ایجاد کنید که رویدادهای HTTP را مدیریت کند. مثال‌های این بخش براساس نمونه «کارساز زمان» است که وقتی درخواست 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');
}

پایان دادن به «توابع 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);

پایتون

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 بیشتر بدانید.