Wenn Sie Cloud Functions in Ihr Projekt einbinden, kann Ihr Code viele unabhängige Funktionen enthalten. Möglicherweise haben Sie zu viele Funktionen, um sie sinnvoll in einer einzigen Datei unterzubringen. Oder verschiedene Teams stellen verschiedene Gruppen von Funktionen bereit, wodurch das Risiko besteht, dass ein Team die Funktionen eines anderen Teams überschreibt oder versehentlich löscht. Cloud Functions bietet verschiedene Möglichkeiten, Ihren Code zu organisieren, um die Navigation und Wartung Ihrer Funktionen zu erleichtern.
Funktionen in Codebases organisieren
Mit der Eigenschaft codebase
des Konfigurationsobjekts für Funktionen in firebase.json
können Sie eine große Sammlung von Funktionen in mehreren Repositorys oder Unterpaketen in einem Monorepo-Setup mit einem einzelnen Repository verwalten:
# firebase.json
"functions": {
"codebase": "my-codebase"
# NOTE: Codebase must be less than 63 characters and can contain only
# lowercase letters, numeric characters, underscores, and dashes.
}
Das Attribut codebase
wird in der Firebase-Befehlszeile ab Version 10.7.1 unterstützt.
Mehrere Repositories verwalten
Das Attribut codebase
kann die Verwaltung mehrerer Repositories vereinfachen. Sehen wir uns einen Fall an, in dem Sie zwei verschiedene Repositories haben, in denen Funktionen für dasselbe Firebase-Projekt bereitgestellt werden:
$ tree .
├── repoA
│ ├── firebase.json
│ └── functions
│ ├── index.js
│ └── package.json
└── repoB
├── firebase.json
└── functions
├── index.js
└── package.json
Ohne Codebasis-Anmerkungen hätte die Firebase CLI Sie bei der Bereitstellung aufgefordert, Funktionen zu löschen, die im anderen Repository definiert sind:
$ (cd repoA && firebase deploy --only functions)
...
i functions: preparing functions directory for uploading...
✔ functions: functions folder uploaded successfully
The following functions are found in your project but do not exist in your local source code:
fn1FromRepoB
fn2FromRepoB
...
? Would you like to proceed with deletion? Selecting no will continue the rest of the deployments. (y/N)
Sie können dieses Problem vermeiden, indem Sie im Bereich „functions“ der Konfiguration von firebase.json
in jedem Projekt-Repository eine eindeutige Annotation für die Codebasis hinzufügen:
# repoA/firebase.json
"functions": {
"codebase": "repo-a"
}
# repoB/firebase.json
"functions": {
"codebase": "repo-b"
}
Dank der Codebase-Anmerkung werden Sie in der Firebase CLI nicht mehr aufgefordert, Funktionen zu löschen, die außerhalb Ihres unmittelbaren Repositorys definiert sind:
$ (cd repoA && firebase deploy --only functions)
...
i functions: preparing functions directory for uploading...
✔ functions: functions folder uploaded successfully
# Gleefully ignores functions from repoB
i functions: creating Node.js 16 function fnFromRepoA (us-central1)...
✔ Deploy Complete!
Mehrere Quellpakete verwalten (Monorepo)
Das Attribut codebase
kann die Verwaltung mehrerer Quellpakete in einem einzelnen Repository vereinfachen. Sehen wir uns einen Fall an, in dem Sie ein Firebase-Projektverzeichnis mit Funktionsdefinitionen haben, die auf mehrere Unterpakete verteilt sind:
$ tree .
├── firebase.json
├── teamA
│ ├── index.js
│ └── package.json
└── teamB
├── index.js
└── package.json
Dieses Setup eignet sich für die folgenden Anwendungsfälle:
- Sie haben ein Monorepo eingerichtet und verschiedene Teams verwalten ihre eigenen Funktionsdefinitionen in einem isolierten Paket.
- Sie haben eine Funktion mit einer starken externen Abhängigkeit und einer zeitaufwendigen Initialisierung und möchten diese Funktion von anderen latenzsensitiven Funktionen isolieren.
Um ein solches Monorepo-Setup zu unterstützen, definieren Sie mehrere Funktionskonfigurationen in firebase.json
:
"functions": [
{
"source": "teamA",
"codebase": "team-a"
},
{
"source": "teamB",
"codebase": "team-b"
},
]
Mit dieser Konfiguration stellt die Firebase CLI Funktionen aus allen Paketen mit einem einzigen Bereitstellungsbefehl bereit:
$ firebase deploy --only functions
i deploying functions
i functions: preparing codebase team-a for deployment
i functions: preparing codebase team-b for deployment
i functions: creating Node.js 16 function team-a:helloATeam(us-central1)...
i functions: creating Node.js 16 function team-b:helloBTeam(us-central1)...
...
Sie können auch eine bestimmte Codebasis bereitstellen:
$ firebase deploy --only functions:team-b
i deploying functions
i functions: preparing codebase team-b for deployment
i functions: updating Node.js 16 function team-b:helloBTeam(us-central1)...
...
Funktionen in mehreren Dateien schreiben
Wenn Sie mit Cloud Functions beginnen, legen Sie die ersten Funktionen möglicherweise in einer einzigen Datei ab:
index.js
const functions = require('firebase-functions/v1');
exports.foo = functions.https.onRequest((request, response) => {
// ...
});
exports.bar = functions.https.onRequest((request, response) => {
// ...
});
main.py
from firebase_functions import https_fn
@https_fn.on_request()
def foo(req: https_fn.Request) -> https_fn.Response:
return https_fn.Response("Hello foo!")
@https_fn.on_request()
def bar(req: https_fn.Request) -> https_fn.Response:
return https_fn.Response("Hello bar!")
Dies kann bei mehr als einigen wenigen Funktionen schwierig zu verwalten sein. Stattdessen können Sie die gesamte Logik für jede Funktion in einer eigenen Datei unterbringen und Ihre Quelldatei als Liste von Exporten verwenden:
Node.js
foo.js
const functions = require('firebase-functions/v1'); exports.foo = functions.https.onRequest((request, response) => { // ... });
bar.js
const functions = require('firebase-functions/v1'); exports.bar = functions.https.onRequest((request, response) => { // ... });
index.js
const foo = require('./foo'); const bar = require('./bar'); exports.foo = foo.foo; exports.bar = bar.bar;
Python
foo.py
from firebase_functions import https_fn
@https_fn.on_request()
def foo(req: https_fn.Request) -> https_fn.Response:
return https_fn.Response("Hello foo!")
bar.py
from firebase_functions import https_fn
@https_fn.on_request()
def bar(req: https_fn.Request) -> https_fn.Response:
return https_fn.Response("Hello foo!")
main.py
from fn_impl.foo import *
from fn_impl.bar import *
Bei dieser Einrichtung wird eine Projektverzeichnisstruktur wie die folgende vorausgesetzt:
my-project
├── firebase.json
└── functions
├── fn_impl
│ ├── __init__.py
│ ├── foo.py
│ └── bar.py
├── main.py
└── requirements.txt
fn_impl
: Kann einen beliebigen Namen haben
__init__.py
: Erforderlich, kann aber leer sein
Gruppenfunktionen
In vielen Projekten können Funktionen in logische Gruppen unterteilt werden, die zusammen bereitgestellt und verwaltet werden sollten. Sie haben beispielsweise eine Gruppe von Funktionen, die für die Berichterstellung verwendet werden:
metrics.js
const functions = require('firebase-functions/v1'); exports.usageStats = functions.https.onRequest((request, response) => { // ... }); exports.nightlyReport = functions.https.onRequest((request, response) => { // ... });
Sie können diese Funktionen beim Exportieren in der Datei index.js
in eine Gruppe einfügen:
index.js
// Export both functions from metrics.js in the "metrics" group: // - metrics-usageStats // - metrics-nightlyReport exports.metrics = require('./metrics');
Bei der Bereitstellung wird den Funktionen der Name ihrer Gruppe vorangestellt. In diesem Beispiel lauten die Funktionen also metrics-usageStats
und metrics-nightlyReport
.
Beim Bereitstellen von Funktionen können Sie die Aktion auf eine einzelne Gruppe beschränken:
firebase deploy --only functions:metrics
Nächste Schritte
Weitere Informationen zu Cloud Functions finden Sie hier: