Mit den SDKs für Cloud-Funktionen für Firebase-Clients können Sie Funktionen direkt von einer Firebase-App aus aufrufen. Um eine Funktion von Ihrer App auf diese Weise aufzurufen, schreiben und implementieren Sie eine HTTPS Callable-Funktion in Cloud-Funktionen und fügen Sie dann eine Client-Logik hinzu, um die Funktion von Ihrer App aus aufzurufen.
Es ist wichtig zu beachten, dass aufrufbare HTTPS-Funktionen ähnlich, aber nicht identisch mit HTTP-Funktionen sind. Um aufrufbare HTTPS-Funktionen verwenden zu können, müssen Sie das Client-SDK für Ihre Plattform zusammen mit der Backend-API functions.https
(oder das Protokoll implementieren). Callables unterscheiden sich in folgenden Punkten von HTTP-Funktionen:
- Bei Callables werden Firebase-Authentifizierungs- und FCM-Token, sofern verfügbar, automatisch in Anforderungen enthalten.
- Der Trigger
functions.https.onCall
deserialisiert automatisch den Anforderungshauptteil und validiert Authentifizierungstoken.
Das Firebase SDK für Cloud-Funktionen v0.9.1 und höher arbeitet mit diesen Firebase-Client-SDK-Mindestversionen zusammen, um aufrufbare HTTPS-Funktionen zu unterstützen:
- Firebase SDK für iOS 7.11.0
- Firebase SDK für Android 19.2.0
- Firebase JavaScript SDK 8.4.1
- Firebase Modular Web SDK Version 9.0
Wenn Sie einer App, die auf einer nicht unterstützten Plattform https.onCall
, ähnliche Funktionen hinzufügen möchten, https.onCall
Sie die Protokollspezifikation für https.onCall
. Der Rest dieses Handbuchs enthält Anweisungen zum Schreiben, Bereitstellen und Aufrufen einer aufrufbaren HTTPS-Funktion für iOS, Android, Web, C ++ und Unity.
Schreiben Sie die aufrufbare Funktion und stellen Sie sie bereit
Verwenden Sie functions.https.onCall
, um eine aufrufbare HTTPS- functions.https.onCall
zu erstellen. Diese Methode verwendet zwei Parameter: data
und optionalen context
:
// Saves a message to the Firebase Realtime Database but sanitizes the text by removing swearwords.
exports.addMessage = functions.https.onCall((data, context) => {
// ...
});
Bei einer aufrufbaren Funktion, die beispielsweise eine Textnachricht in der Echtzeitdatenbank speichert, können data
den Nachrichtentext enthalten, während context
Benutzerauthentifizierungsinformationen darstellen:
// Message text passed from the client.
const text = data.text;
// Authentication / user information is automatically added to the request.
const uid = context.auth.uid;
const name = context.auth.token.name || null;
const picture = context.auth.token.picture || null;
const email = context.auth.token.email || null;
Die Entfernung zwischen dem Standort der aufrufbaren Funktion und dem Standort des aufrufenden Clients kann zu einer Netzwerklatenz führen. Um die Leistung zu optimieren, sollten Sie gegebenenfalls den Speicherort der Funktion angeben und sicherstellen, dass der Speicherort des aufrufbaren Objekts mit dem Speicherort übereinstimmt, der beim Initialisieren des SDK auf der Clientseite festgelegt wurde.
Senden Sie das Ergebnis zurück
Um Daten an den Client zurückzusenden, geben Sie Daten zurück, die JSON-codiert werden können. So geben Sie beispielsweise das Ergebnis einer Additionsoperation zurück:
// returning result.
return {
firstNumber: firstNumber,
secondNumber: secondNumber,
operator: '+',
operationResult: firstNumber + secondNumber,
};
Geben Sie ein Versprechen zurück, um Daten nach einer asynchronen Operation zurückzugeben. Die vom Versprechen zurückgegebenen Daten werden an den Kunden zurückgesendet. Sie können beispielsweise bereinigten Text zurückgeben, den die aufrufbare Funktion in die Echtzeitdatenbank geschrieben hat:
// Saving the new message to the Realtime Database.
const sanitizedMessage = sanitizer.sanitizeText(text); // Sanitize the message.
return admin.database().ref('/messages').push({
text: sanitizedMessage,
author: { uid, name, picture, email },
}).then(() => {
console.log('New Message written');
// Returning the sanitized message to the client.
return { text: sanitizedMessage };
})
Behandeln Sie Fehler
Um sicherzustellen, dass der Client nützliche Fehlerdetails erhält, geben Sie Fehler von einem aufrufbaren Objekt zurück, indem Sie eine Instanz von functions.https.HttpsError
auslösen (oder ein abgelehntes Versprechen zurückgeben). Der Fehler hat ein code
, das einer der unter functions.https.HttpsError
aufgelisteten Werte sein functions.https.HttpsError
. Die Fehler haben auch eine String - message
, die standardmäßig auf eine leere Zeichenfolge. Sie können auch ein optionales details
mit einem beliebigen Wert haben. Wenn ein anderer Fehler als HttpsError
von Ihren Funktionen HttpsError
wird, erhält Ihr Client stattdessen einen Fehler mit der Meldung INTERNAL
und dem internal
Code.
Beispielsweise könnte eine Funktion Datenüberprüfungs- und Authentifizierungsfehler mit Fehlermeldungen auslösen, um zum aufrufenden Client zurückzukehren:
// Checking attribute.
if (!(typeof text === 'string') || text.length === 0) {
// Throwing an HttpsError so that the client gets the error details.
throw new functions.https.HttpsError('invalid-argument', 'The function must be called with ' +
'one arguments "text" containing the message text to add.');
}
// Checking that the user is authenticated.
if (!context.auth) {
// Throwing an HttpsError so that the client gets the error details.
throw new functions.https.HttpsError('failed-precondition', 'The function must be called ' +
'while authenticated.');
}
Stellen Sie die aufrufbare Funktion bereit
Nachdem Sie eine abgeschlossene aufrufbare Funktion in index.js
, wird sie zusammen mit allen anderen Funktionen index.js
, wenn Sie die firebase deploy
ausführen. Verwenden Sie das Argument --only
wie gezeigt, um Teilbereitstellungen durchzuführen, um nur die aufrufbaren --only
:
$ firebase deploy --only functions:addMessage
Wenn beim Bereitstellen von Funktionen Berechtigungsfehler auftreten, stellen Sie sicher, dass dem Benutzer, der die Bereitstellungsbefehle ausführt, die entsprechenden IAM-Rollen zugewiesen sind.
Richten Sie Ihre Client-Entwicklungsumgebung ein
Stellen Sie sicher, dass Sie alle Voraussetzungen erfüllen, und fügen Sie Ihrer App die erforderlichen Abhängigkeiten und Clientbibliotheken hinzu.
iOS
- Befolgen Sie die Anweisungen, um Firebase zu Ihrer iOS-App hinzuzufügen .
- Fügen Sie den Pod für Cloud-Funktionen zu Ihrer
Podfile
:pod 'Firebase/Functions'
- Speichern Sie die Datei und führen Sie Folgendes aus:
pod install
Web v9
- Befolgen Sie die Anweisungen, um Firebase zu Ihrer Web-App hinzuzufügen .
- Fügen Sie Ihrer App die Clientbibliotheken Firebase Core und Cloud Functions hinzu:
<script src="https://www.gstatic.com/firebasejs/8.4.1/firebase.js"></script> <script src="https://www.gstatic.com/firebasejs/8.4.1/firebase-functions.js"></script>
Das Cloud Functions SDK ist auch als npm-Paket erhältlich.
- Führen Sie den folgenden Befehl von Ihrem Terminal aus:
npm install firebase@8.4.1 --save
Manuell benötigen Sie sowohl Firebase-Kern- als auch Cloud-Funktionen:
import { initializeApp } from 'firebase/app'; import { initializeFunctions } from 'firebase/functions';
const app = initializeApp({ projectId: '### CLOUD FUNCTIONS PROJECT ID ###', apiKey: '### FIREBASE API KEY ###', authDomain: '### FIREBASE AUTH DOMAIN ###', }); const functions = initializeFunctions(app);
Web v8
- Befolgen Sie die Anweisungen, um Firebase zu Ihrer Web-App hinzuzufügen .
- Fügen Sie Ihrer App die Clientbibliotheken Firebase Core und Cloud Functions hinzu:
<script src="https://www.gstatic.com/firebasejs/8.4.1/firebase.js"></script> <script src="https://www.gstatic.com/firebasejs/8.4.1/firebase-functions.js"></script>
Das Cloud Functions SDK ist auch als npm-Paket erhältlich.
- Führen Sie den folgenden Befehl von Ihrem Terminal aus:
npm install firebase@8.4.1 --save
- Manuell benötigen Sie sowohl Firebase-Kern- als auch Cloud-Funktionen:
const firebase = require("firebase"); // Required for side-effects require("firebase/functions");
Java
Befolgen Sie die Anweisungen, um Firebase zu Ihrer Android-App hinzuzufügen .
Deklarieren Sie mithilfe der Firebase-Android-BoM die Abhängigkeit für die Cloud-Funktionen-Android-Bibliothek in Ihrer Gradle-Datei auf Modulebene (App-Ebene) (normalerweise
app/build.gradle
).dependencies { // Import the BoM for the Firebase platform implementation platform('com.google.firebase:firebase-bom:27.1.0') // Declare the dependency for the Cloud Functions library // When using the BoM, you don't specify versions in Firebase library dependencies implementation 'com.google.firebase:firebase-functions' }
Bei Verwendung der Firebase Android BoM verwendet Ihre App immer kompatible Versionen der Firebase Android-Bibliotheken.
(Alternative) Deklarieren Sie Firebase-Bibliotheksabhängigkeiten, ohne die Stückliste zu verwenden
Wenn Sie die Firebase-Stückliste nicht verwenden möchten, müssen Sie jede Firebase-Bibliotheksversion in ihrer Abhängigkeitszeile angeben.
Wenn Sie mehrere Firebase-Bibliotheken in Ihrer App verwenden, empfehlen wir dringend, die Stückliste zum Verwalten von Bibliotheksversionen zu verwenden, um sicherzustellen, dass alle Versionen kompatibel sind.
dependencies { // Declare the dependency for the Cloud Functions library // When NOT using the BoM, you must specify versions in Firebase library dependencies implementation 'com.google.firebase:firebase-functions:19.2.0' }
Kotlin + KTX
Befolgen Sie die Anweisungen, um Firebase zu Ihrer Android-App hinzuzufügen .
Deklarieren Sie mithilfe der Firebase-Android-BoM die Abhängigkeit für die Cloud-Funktionen-Android-Bibliothek in Ihrer Gradle-Datei auf Modulebene (App-Ebene) (normalerweise
app/build.gradle
).dependencies { // Import the BoM for the Firebase platform implementation platform('com.google.firebase:firebase-bom:27.1.0') // Declare the dependency for the Cloud Functions library // When using the BoM, you don't specify versions in Firebase library dependencies implementation 'com.google.firebase:firebase-functions-ktx' }
Bei Verwendung der Firebase Android BoM verwendet Ihre App immer kompatible Versionen der Firebase Android-Bibliotheken.
(Alternative) Deklarieren Sie Firebase-Bibliotheksabhängigkeiten, ohne die Stückliste zu verwenden
Wenn Sie die Firebase-Stückliste nicht verwenden möchten, müssen Sie jede Firebase-Bibliotheksversion in ihrer Abhängigkeitszeile angeben.
Wenn Sie mehrere Firebase-Bibliotheken in Ihrer App verwenden, empfehlen wir dringend, die Stückliste zum Verwalten von Bibliotheksversionen zu verwenden, um sicherzustellen, dass alle Versionen kompatibel sind.
dependencies { // Declare the dependency for the Cloud Functions library // When NOT using the BoM, you must specify versions in Firebase library dependencies implementation 'com.google.firebase:firebase-functions-ktx:19.2.0' }
C ++
Für C ++ mit Android :
- Befolgen Sie die Anweisungen, um Firebase zu Ihrem C ++ - Projekt hinzuzufügen .
- Fügen Sie die
firebase_functions
Bibliothek zu IhrerCMakeLists.txt
Datei.
Für C ++ mit iOS :
- Befolgen Sie die Anweisungen, um Firebase zu Ihrem C ++ - Projekt hinzuzufügen .
- Fügen Sie den Pod für Cloud-Funktionen zu Ihrer
Podfile
:pod 'Firebase/Functions'
- Speichern Sie die Datei und führen Sie Folgendes aus:
pod install
- Fügen Sie Ihrem Xcode-Projekt die Frameworks Firebase Core und Cloud Functions aus dem Firebase C ++ SDK hinzu .
-
firebase.framework
-
firebase_functions.framework
-
Einheit
- Befolgen Sie die Anweisungen, um Firebase zu Ihrem Unity-Projekt hinzuzufügen .
- Fügen Sie das
FirebaseFunctions.unitypackage
aus dem Firebase Unity SDK zu Ihrem Unity-Projekt hinzu.
Initialisieren Sie das Client-SDK
Initialisieren Sie eine Instanz von Cloud-Funktionen:
Schnell
lazy var functions = Functions.functions()
Ziel c
@property(strong, nonatomic) FIRFunctions *functions;
// ...
self.functions = [FIRFunctions functions];
Web v8
firebase.initializeApp({
apiKey: '### FIREBASE API KEY ###',
authDomain: '### FIREBASE AUTH DOMAIN ###',
projectId: '### CLOUD FUNCTIONS PROJECT ID ###'
databaseURL: 'https://### YOUR DATABASE NAME ###.firebaseio.com',
});
// Initialize Cloud Functions through Firebase
var functions = firebase.functions();
Web v9
initializeApp({
projectId: '### CLOUD FUNCTIONS PROJECT ID ###',
apiKey: '### FIREBASE API KEY ###',
authDomain: '### FIREBASE AUTH DOMAIN ###',
});
Java
private FirebaseFunctions mFunctions; // ... mFunctions = FirebaseFunctions.getInstance();
Kotlin + KTX
private lateinit var functions: FirebaseFunctions // ... functions = Firebase.functions
C ++
firebase::functions::Functions* functions;
// ...
functions = firebase::functions::Functions::GetInstance(app);
Einheit
functions = Firebase.Functions.DefaultInstance;
Rufen Sie die Funktion auf
Schnell
functions.httpsCallable("addMessage").call(["text": inputField.text]) { (result, error) in
if let error = error as NSError? {
if error.domain == FunctionsErrorDomain {
let code = FunctionsErrorCode(rawValue: error.code)
let message = error.localizedDescription
let details = error.userInfo[FunctionsErrorDetailsKey]
}
// ...
}
if let text = result?.data as? String {
self.resultField.text = text
}
}
Ziel c
[[_functions HTTPSCallableWithName:@"addMessage"] callWithObject:@{@"text": _inputField.text}
completion:^(FIRHTTPSCallableResult * _Nullable result, NSError * _Nullable error) {
if (error) {
if (error.domain == FIRFunctionsErrorDomain) {
FIRFunctionsErrorCode code = error.code;
NSString *message = error.localizedDescription;
NSObject *details = error.userInfo[FIRFunctionsErrorDetailsKey];
}
// ...
}
self->_resultField.text = result.data;
}];
Web v8
var addMessage = firebase.functions().httpsCallable('addMessage');
addMessage({ text: messageText })
.then((result) => {
// Read result of the Cloud Function.
var sanitizedMessage = result.data.text;
});
Web v9
import { getFunctions, httpsCallable } from "firebase/functions";
const functions = getFunctions();
const addMessage = httpsCallable(functions, 'addMessage');
addMessage({ text: messageText })
.then((result) => {
// Read result of the Cloud Function.
/** @type {any} */
const data = result.data;
const sanitizedMessage = data.text;
});
Java
private Task<String> addMessage(String text) { // Create the arguments to the callable function. Map<String, Object> data = new HashMap<>(); data.put("text", text); data.put("push", true); return mFunctions .getHttpsCallable("addMessage") .call(data) .continueWith(new Continuation<HttpsCallableResult, String>() { @Override public String then(@NonNull Task<HttpsCallableResult> task) throws Exception { // This continuation runs on either success or failure, but if the task // has failed then getResult() will throw an Exception which will be // propagated down. String result = (String) task.getResult().getData(); return result; } }); }
Kotlin + KTX
private fun addMessage(text: String): Task<String> { // Create the arguments to the callable function. val data = hashMapOf( "text" to text, "push" to true ) return functions .getHttpsCallable("addMessage") .call(data) .continueWith { task -> // This continuation runs on either success or failure, but if the task // has failed then result will throw an Exception which will be // propagated down. val result = task.result?.data as String result } }
C ++
firebase::Future<firebase::functions::HttpsCallableResult> AddMessage(
const std::string& text) {
// Create the arguments to the callable function.
firebase::Variant data = firebase::Variant::EmptyMap();
data.map()["text"] = firebase::Variant(text);
data.map()["push"] = true;
// Call the function and add a callback for the result.
firebase::functions::HttpsCallableReference doSomething =
functions->GetHttpsCallable("addMessage");
return doSomething.Call(data);
}
Einheit
private Task<string> addMessage(string text) {
// Create the arguments to the callable function.
var data = new Dictionary<string, object>();
data["text"] = text;
data["push"] = true;
// Call the function and extract the operation from the result.
var function = functions.GetHttpsCallable("addMessage");
return function.CallAsync(data).ContinueWith((task) => {
return (string) task.Result.Data;
});
}
Behandeln Sie Fehler auf dem Client
Der Client erhält einen Fehler, wenn der Server einen Fehler ausgegeben hat oder wenn das resultierende Versprechen abgelehnt wurde.
Wenn der Fehler von der Funktion zurück vom Typ function.https.HttpsError
, dann erhält der Kunde den Fehler - code
, message
und details
aus den Server - Fehlern. Andernfalls enthält der Fehler die Meldung INTERNAL
und den Code INTERNAL
. In der Anleitung finden Sie Informationen zum Umgang mit Fehlern in Ihrer aufrufbaren Funktion.
Schnell
if let error = error as NSError? {
if error.domain == FunctionsErrorDomain {
let code = FunctionsErrorCode(rawValue: error.code)
let message = error.localizedDescription
let details = error.userInfo[FunctionsErrorDetailsKey]
}
// ...
}
Ziel c
if (error) {
if (error.domain == FIRFunctionsErrorDomain) {
FIRFunctionsErrorCode code = error.code;
NSString *message = error.localizedDescription;
NSObject *details = error.userInfo[FIRFunctionsErrorDetailsKey];
}
// ...
}
Web v8
var addMessage = firebase.functions().httpsCallable('addMessage');
addMessage({ text: messageText })
.then((result) => {
// Read result of the Cloud Function.
var sanitizedMessage = result.data.text;
})
.catch((error) => {
// Getting the Error details.
var code = error.code;
var message = error.message;
var details = error.details;
// ...
});
Web v9
import { getFunctions, httpsCallable } from "firebase/functions";
const functions = getFunctions();
const addMessage = httpsCallable(functions, 'addMessage');
addMessage({ text: messageText })
.then((result) => {
// Read result of the Cloud Function.
/** @type {any} */
const data = result.data;
const sanitizedMessage = data.text;
})
.catch((error) => {
// Getting the Error details.
const code = error.code;
const message = error.message;
const details = error.details;
// ...
});
Java
addMessage(inputMessage) .addOnCompleteListener(new OnCompleteListener<String>() { @Override public void onComplete(@NonNull Task<String> task) { if (!task.isSuccessful()) { Exception e = task.getException(); if (e instanceof FirebaseFunctionsException) { FirebaseFunctionsException ffe = (FirebaseFunctionsException) e; FirebaseFunctionsException.Code code = ffe.getCode(); Object details = ffe.getDetails(); } // ... } // ... } });
Kotlin + KTX
addMessage(inputMessage) .addOnCompleteListener(OnCompleteListener { task -> if (!task.isSuccessful) { val e = task.exception if (e is FirebaseFunctionsException) { val code = e.code val details = e.details } // ... } // ... })
C ++
void OnAddMessageCallback(
const firebase::Future<firebase::functions::HttpsCallableResult>& future) {
if (future.error() != firebase::functions::kErrorNone) {
// Function error code, will be kErrorInternal if the failure was not
// handled properly in the function call.
auto code = static_cast<firebase::functions::Error>(future.error());
// Display the error in the UI.
DisplayError(code, future.error_message());
return;
}
const firebase::functions::HttpsCallableResult *result = future.result();
firebase::Variant data = result->data();
// This will assert if the result returned from the function wasn't a string.
std::string message = data.string_value();
// Display the result in the UI.
DisplayResult(message);
}
// ...
// ...
auto future = AddMessage(message);
future.OnCompletion(OnAddMessageCallback);
// ...
Einheit
addMessage(text).ContinueWith((task) => {
if (task.IsFaulted) {
foreach (var inner in task.Exception.InnerExceptions) {
if (inner is FunctionsException) {
var e = (FunctionsException) inner;
// Function error code, will be INTERNAL if the failure
// was not handled properly in the function call.
var code = e.ErrorCode;
var message = e.ErrorMessage;
}
}
} else {
string result = task.Result;
}
});