Catch up on everthing we announced at this year's Firebase Summit. Learn more

Appeler des fonctions depuis votre application

Les SDK clients Cloud Functions for Firebase vous permettent d'appeler des fonctions directement depuis une application Firebase. Pour appeler une fonction depuis votre application de cette manière, écrivez et déployez une fonction appelable HTTPS dans Cloud Functions, puis ajoutez une logique client pour appeler la fonction depuis votre application.

Il est important de garder à l' esprit que HTTPS fonctions appelables sont similaires mais pas identiques aux fonctions HTTP. Pour utiliser HTTPS fonctions appelables vous devez utiliser le SDK client pour votre plate - forme ainsi que les functions.https de l' API (ou mettre en œuvre le protocole). Les callables présentent ces différences clés par rapport aux fonctions HTTP :

  • Avec les callables, les jetons Firebase Authentication, les jetons FCM et les jetons App Check, lorsqu'ils sont disponibles, sont automatiquement inclus dans les demandes.
  • Le functions.https.onCall déclencheur désérialise automatiquement le corps de la requête et valide auth jetons.

Le SDK Firebase pour Cloud Functions v0.9.1 et versions ultérieures interagit avec ces versions minimales du SDK client Firebase pour prendre en charge les fonctions HTTPS appelables :

  • SDK Firebase pour les plates-formes Apple 8.10.0
  • SDK Firebase pour Android 20.0.1
  • SDK JavaScript Firebase 8.10.0
  • SDK Web modulaire Firebase v. 9.0

Si vous souhaitez ajouter une fonctionnalité similaire à une application construite sur une plate - forme non prise en charge, voir le protocole Spécification pour https.onCall . Le reste de ce guide fournit des instructions sur la façon d'écrire, de déployer et d'appeler une fonction appelable HTTPS pour les plates-formes Apple, Android, Web, C++ et Unity.

Écrire et déployer la fonction appelable

Utilisez functions.https.onCall pour créer une HTTPS fonction appelable. Cette méthode prend deux paramètres: data , et en option context :

// Saves a message to the Firebase Realtime Database but sanitizes the text by removing swearwords.
exports.addMessage = functions.https.onCall((data, context) => {
  // ...
});

Pour une fonction appelable qui enregistre un message texte à la base de données en temps réel, par exemple, les data pourraient contenir le texte du message, alors que context paramètres représentent des informations auth utilisateur:

// 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;

La distance entre l'emplacement de la fonction appelable et l'emplacement du client appelant peut créer une latence du réseau. Pour optimiser les performances, en spécifiant l' emplacement de la fonction , le cas échéant, et assurez - vous d'aligner l'emplacement du appelable avec l'ensemble de l' emplacement lorsque vous initialisez le SDK du côté client.

Vous pouvez éventuellement joindre une attestation App Check pour protéger vos ressources backend contre les abus, tels que la facturation frauduleuse ou le phishing. Voir Activer App Vérifier l' application des fonctions de Cloud .

Envoi du résultat

Pour renvoyer des données au client, renvoyez des données pouvant être encodées en JSON. Par exemple, pour renvoyer le résultat d'une opération d'addition :

// returning result.
return {
  firstNumber: firstNumber,
  secondNumber: secondNumber,
  operator: '+',
  operationResult: firstNumber + secondNumber,
};

Pour renvoyer des données après une opération asynchrone, renvoyez une promesse. Les données renvoyées par la promesse sont renvoyées au client. Par exemple, vous pouvez renvoyer le texte épuré que la fonction appelable a écrit dans la base de données en temps réel :

// 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 };
})

Gérer les erreurs

Pour assurer que le client obtient les détails d'erreur utiles, les erreurs de retour d'un appelable en lançant (ou le retour d' une promesse rejetée avec) une instance de functions.https.HttpsError . L'erreur a un code de l' attribut qui peut être l' une des valeurs énumérées à functions.https.HttpsError . Les erreurs ont aussi une chaîne un message , qui est par défaut à une chaîne vide. Ils peuvent aussi avoir une option de details terrain avec une valeur arbitraire. Si une autre erreur que HttpsError est jeté de vos fonctions, votre client reçoit plutôt une erreur avec le message INTERNAL et le code internal .

Par exemple, une fonction peut générer des erreurs de validation et d'authentification des données avec des messages d'erreur à renvoyer au client appelant :

// 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.');
}

Déployer la fonction appelable

Après avoir enregistré une fonction appelable terminé dans index.js , il est déployé en même temps que toutes les autres fonctions lorsque vous exécutez firebase deploy . Pour déployer uniquement le appelable, utilisez le --only argument comme indiqué pour effectuer Déploie partielles :

$ firebase deploy --only functions:addMessage

Si vous rencontrez des erreurs d'autorisations lors du déploiement de fonctions, assurez - vous que les appropriés rôles IAM sont attribués à l'utilisateur exécutant les commandes de déploiement.

Configurer votre environnement de développement client

Assurez-vous de remplir toutes les conditions préalables, puis ajoutez les dépendances et les bibliothèques clientes requises à votre application.

iOS+

Suivez les instructions pour ajouter Firebase à votre application d' Apple .

Utilisez Swift Package Manager pour installer et gérer les dépendances de Firebase.

  1. Dans Xcode, avec votre projet d'application ouvert, accédez à Fichier> Paquets Swift> Ajouter un package de dépendance.
  2. Lorsque vous y êtes invité, ajoutez le référentiel SDK des plates-formes Firebase Apple :
  3.   https://github.com/firebase/firebase-ios-sdk
      
  4. Choisissez la bibliothèque Cloud Functions.
  5. Une fois terminé, Xcode commencera automatiquement à résoudre et à télécharger vos dépendances en arrière-plan.

Web version 9

  1. Suivez les instructions pour ajouter Firebase à votre application Web . Assurez - vous d'exécuter la commande suivante à partir de votre terminal:
    npm install firebase@9.6.0 --save
    
  2. Nécessite manuellement à la fois Firebase core et Cloud Functions :

     import { initializeApp } from 'firebase/app';
     import { getFunctions } from 'firebase/functions';
    
     const app = initializeApp({
         projectId: '### CLOUD FUNCTIONS PROJECT ID ###',
         apiKey: '### FIREBASE API KEY ###',
         authDomain: '### FIREBASE AUTH DOMAIN ###',
       });
     const functions = getFunctions(app);
    

Web version 8

  1. Suivez les instructions pour ajouter Firebase à votre application Web .
  2. Ajouter le noyau Firebase et fonctions de Cloud bibliothèques clientes à votre application:
    <script src="https://www.gstatic.com/firebasejs/8.10.0/firebase.js"></script>
    <script src="https://www.gstatic.com/firebasejs/8.10.0/firebase-functions.js"></script>
    

Le SDK Cloud Functions est également disponible sous forme de package npm.

  1. Exécutez la commande suivante à partir de votre terminal:
    npm install firebase@8.10.0 --save
    
  2. Exigent manuellement à la fois noyau Firebase et fonctions Cloud:
    const firebase = require("firebase");
    // Required for side-effects
    require("firebase/functions");
    

Java

  1. Suivez les instructions pour ajouter Firebase à votre application Android .

  2. Utilisation de la Firebase Android BoM , déclarer la dépendance pour les fonctions de Cloud bibliothèque Android dans votre module (app-niveau) de fichier Gradle (généralement app/build.gradle ).

    dependencies {
        // Import the BoM for the Firebase platform
        implementation platform('com.google.firebase:firebase-bom:29.0.1')
    
        // 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'
    }
    

    En utilisant le Firebase Android BoM , votre application utilise toujours des versions compatibles des bibliothèques Firebase Android.

    (Alternative) déclarer des dépendances de bibliothèque firebase sans utiliser la nomenclature

    Si vous choisissez de ne pas utiliser la nomenclature de Firebase, vous devez spécifier chaque version de la bibliothèque Firebase dans sa ligne de dépendance.

    Notez que si vous utilisez plusieurs bibliothèques Firebase dans votre application, nous vous recommandons fortement d' utiliser la BoM pour gérer les versions bibliothèque, ce qui garantit que toutes les versions sont compatibles.

    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:20.0.1'
    }
    

Kotlin+KTX

  1. Suivez les instructions pour ajouter Firebase à votre application Android .

  2. Utilisation de la Firebase Android BoM , déclarer la dépendance pour les fonctions de Cloud bibliothèque Android dans votre module (app-niveau) de fichier Gradle (généralement app/build.gradle ).

    dependencies {
        // Import the BoM for the Firebase platform
        implementation platform('com.google.firebase:firebase-bom:29.0.1')
    
        // 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'
    }
    

    En utilisant le Firebase Android BoM , votre application utilise toujours des versions compatibles des bibliothèques Firebase Android.

    (Alternative) déclarer des dépendances de bibliothèque firebase sans utiliser la nomenclature

    Si vous choisissez de ne pas utiliser la nomenclature de Firebase, vous devez spécifier chaque version de la bibliothèque Firebase dans sa ligne de dépendance.

    Notez que si vous utilisez plusieurs bibliothèques Firebase dans votre application, nous vous recommandons fortement d' utiliser la BoM pour gérer les versions bibliothèque, ce qui garantit que toutes les versions sont compatibles.

    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:20.0.1'
    }
    

C++

C ++ avec Android:

  1. Suivez les instructions pour ajouter Firebase à votre projet C ++ .
  2. Ajouter la firebase_functions bibliothèque à votre CMakeLists.txt fichier.

C ++ avec les plates - formes d' Apple:

  1. Suivez les instructions pour ajouter Firebase à votre projet C ++ .
  2. Ajoutez les fonctions Nuage pod à votre Podfile :
    pod 'Firebase/Functions'
  3. Enregistrez le fichier, puis exécutez:
    pod install
  4. Ajouter les cadres de fonctions de base et de nuages Firebase du Firebase C ++ SDK à votre projet Xcode.
    • firebase.framework
    • firebase_functions.framework

Unité

  1. Suivez les instructions pour ajouter Firebase à votre projet Unity .
  2. Ajouter le FirebaseFunctions.unitypackage de l' unité Firebase SDK à votre projet Unity.

Initialiser le SDK client

Initialisez une instance de Cloud Functions :

Rapide

lazy var functions = Functions.functions()

Objectif c

@property(strong, nonatomic) FIRFunctions *functions;
// ...
self.functions = [FIRFunctions functions];

Web version 8

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 version 9

const app = initializeApp({
  projectId: '### CLOUD FUNCTIONS PROJECT ID ###',
  apiKey: '### FIREBASE API KEY ###',
  authDomain: '### FIREBASE AUTH DOMAIN ###',
});
const functions = getFunctions(app);

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);

Unité

functions = Firebase.Functions.DefaultInstance;

Appeler la fonction

Rapide

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 data = result?.data as? [String: Any], let text = data["text"] as? String {
    self.resultField.text = text
  }
}

Objectif 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[@"text"];
}];

Web version 8

var addMessage = firebase.functions().httpsCallable('addMessage');
addMessage({ text: messageText })
  .then((result) => {
    // Read result of the Cloud Function.
    var sanitizedMessage = result.data.text;
  });

Web version 9

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);
}

Unité

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;
  });
}

Gérer les erreurs sur le client

Le client reçoit une erreur si le serveur a généré une erreur ou si la promesse résultante a été rejetée.

Si l'erreur renvoyée par la fonction est de type function.https.HttpsError , le client reçoit l'erreur de code , un message et les details de l'erreur du serveur. Dans le cas contraire, l'erreur contient le message INTERNAL et le code INTERNAL . Voir conseils sur la façon de gérer les erreurs dans votre fonction appelable.

Rapide

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]
  }
  // ...
}

Objectif c

if (error) {
  if (error.domain == FIRFunctionsErrorDomain) {
    FIRFunctionsErrorCode code = error.code;
    NSString *message = error.localizedDescription;
    NSObject *details = error.userInfo[FIRFunctionsErrorDetailsKey];
  }
  // ...
}

Web version 8

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 version 9

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);
  // ...

Unité

 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;
  }
});

Avant de lancer votre application, vous devez activer App Check pour vous assurer que seules vos applications peuvent accéder à vos critères d' évaluation de la fonction appelable.