Mehrere Funktionen organisieren


Wenn Sie Cloud Functions in Ihr Projekt einbinden, kann Ihr Code erweitert werden, um viele unabhängige Funktionen zu enthalten. Möglicherweise haben Sie zu viele Funktionen, um angemessen in eine einzelne Datei zu passen, 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 codebase-Eigenschaft des Konfigurationsobjekts „functions“ in firebase.json können Sie eine große Sammlung von Funktionen in mehreren Repositories oder Unterpaketen innerhalb einer einzelnen Monorepo-Repository-Einrichtung 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 CLI ab Version 10.7.1 unterstützt.

Mehrere Repositories verwalten

Mit der Property codebase lässt sich die Verwaltung mehrerer Repositories vereinfachen. Betrachten wir einen Fall, bei dem Sie zwei verschiedene Repositories haben, die Funktionen für dasselbe Firebase-Projekt bereitstellen:

$  tree .
├── repoA
│   ├── firebase.json
│   └── functions
│       ├── index.js
│       └── package.json
└── repoB
    ├── firebase.json
    └── functions
        ├── index.js
        └── package.json

Ohne Anmerkungen zur Codebasis würden Sie von der Firebase CLI beim Bereitstellen 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 in jedem Projekt-Repository im Abschnitt zur Funktionskonfiguration von firebase.json eine eindeutige Codebasis-Annotation hinzufügen:

# repoA/firebase.json
"functions": {
  "codebase": "repo-a"
}

# repoB/firebase.json
"functions": {
  "codebase": "repo-b"
}

Wenn Sie die Codebasis annotieren, werden Sie in der Firebase CLI nicht mehr aufgefordert, Funktionen zu löschen, die außerhalb Ihres unmittelbaren Repositories 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)

Mit dem Attribut codebase lässt sich die Verwaltung mehrerer Quellpakete in einem einzigen Repository vereinfachen. Angenommen, Sie haben ein FireBase-Projektverzeichnis mit Funktionsdefinitionen, die auf mehrere Unterpakete verteilt sind:

$  tree .
├── firebase.json
├── teamA
│   ├── index.js
│   └── package.json
└── teamB
    ├── index.js
    └── package.json

Diese Konfiguration eignet sich für die folgenden Anwendungsfälle:

  • Sie haben ein Monorepo eingerichtet und verschiedene Teams verwalten ihre eigenen Funktionsdefinitionen in einem separaten Paket.
  • Sie haben eine Funktion mit einer hohen externen Abhängigkeit und einer langwierigen Initialisierung und möchten diese Funktion von anderen latenzempfindlichen Funktionen isolieren.

Um eine solche Monrepo-Einrichtung zu unterstützen, definieren Sie in firebase.json mehrere Funktionskonfigurationen:

"functions": [
  {
    "source": "teamA",
    "codebase": "team-a"
  },
  {
    "source": "teamB",
    "codebase": "team-b"
  },
]

Mit dieser Konfiguration werden mit der Firebase CLI Funktionen aus allen Paketen mit einem einzigen Bereitstellungsbefehl bereitgestellt:

$ 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

Bei den ersten Schritten mit Cloud Functions können Sie die ersten Funktionen in einer einzigen Datei zusammenfassen:

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 mit mehr als nur wenigen Funktionen schwierig sein. Stattdessen können Sie die gesamte Logik für jede Funktion in einer eigenen Datei ablegen 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: Darf einen beliebigen Namen haben

__init__.py: Erforderlich, kann aber leer sein

Funktionen gruppieren

In vielen Projekten können Funktionen in logische Gruppen unterteilt werden, die gemeinsam bereitgestellt und verwaltet werden sollten. Sie könnten beispielsweise eine Gruppe von Funktionen für Berichtsmesswerte verwenden:

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 in eine Gruppe einfügen, wenn Sie sie in die Datei index.js exportieren:

index.js


// Export both functions from metrics.js in the "metrics" group:
//  - metrics-usageStats
//  - metrics-nightlyReport
exports.metrics = require('./metrics');

Nach der Bereitstellung wird Funktionen der Name ihrer Gruppe vorangestellt, sodass die Funktionen in diesem Beispiel metrics-usageStats und metrics-nightlyReport heißen würden.

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 unter: