وظائف الاستدعاء من خلال طلبات HTTP

يمكنك تشغيل دالة من خلال طلب HTTP باستخدام معالج الطلبات. يتيح لك ذلك استدعاء دالة من خلال طرق HTTP التالية المتوافقة: GET وPOST وPUT وDELETE وOPTIONS.

يفترض هذا الدليل أنّك أكملت مهام الإعداد الموضّحة في دليل البدء في Node.js وPython أو مهام الإعداد لحزمة تطوير البرامج (SDK) التجريبية في Dart.

خيارات HTTP إضافية

Option الوصف
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) بشكلٍ صريح من خلال ضبط الخيار 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(List<String> args) {
  fireUp(args, (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 إلى نقطة نهاية الدوال. تستردّ الدالة النموذجية وقت الخادم الحالي، وتنسّقه كما هو محدّد في مَعلمة طلب بحث عنوان 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()، تختبر الدالة كلاً من مَعلمة عنوان URL ونص الطلب بحثًا عن قيمة format لضبط تنسيق التاريخ/الوقت الذي سيتم استخدامه:

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

يمكنك ربط دالة HTTP بـ Firebase Hosting. يمكن توجيه الطلبات على موقعك الإلكتروني على Firebase Hosting إلى دوال HTTP محدّدة. يتيح لك ذلك أيضًا استخدام نطاقك المخصّص مع دالة HTTP. مزيد من المعلومات حول ربط Cloud Functions بـ Firebase Hosting.