透過 HTTP 要求呼叫函式

您可以使用要求處理常式,透過 HTTP 要求觸發函式。這樣一來,您就能透過下列支援的 HTTP 方法叫用函式:GET、POST、PUT、DELETE 和 OPTIONS。

本指南假設您已完成 Node.js 和 Python 入門指南所述的設定工作,或實驗性 Dart SDK 的設定工作。

其他 HTTP 選項

選項 說明
region HTTP 函式可指定一組區域,也可指定單一區域。如果指定多個區域,系統會為每個區域部署個別的函式執行個體。
timeoutSeconds (Python 則為 timeout_sec) 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!");
  }
);

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 要求時,就會觸發該範例。範例函式會擷取目前的伺服器時間、按照網址查詢參數中指定的格式設定時間,並在 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 函式後,您可以透過其專屬網址叫用函式。請使用部署後 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;

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() 結尾。否則,函式可能會繼續執行,並由系統強制終止。另請參閱同步、非同步和 Promise。

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 網站上的要求可以透過 Proxy 傳送至特定 HTTP 函式。這也讓您能搭配 HTTP 函式使用自己的自訂網域。進一步瞭解如何將 Cloud Functions 連結至 Firebase Hosting。