欢迎参加我们将于 2022 年 10 月 18 日举办的 Firebase 峰会(线上线下同时进行),了解 Firebase 如何帮助您加快应用开发速度、满怀信心地发布应用并在之后需要时轻松地扩大应用规模。立即报名

Fonctions d'appel depuis votre application

Les SDK client Cloud Functions pour Firebase vous permettent d'appeler des fonctions directement à partir d'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 les fonctions appelables HTTPS sont similaires mais pas identiques aux fonctions HTTP. Notez également que la signature de rappel a changé entre la v1 et la v2 :

// Adds two numbers to each other.
exports.addnumbers = onCall((request) => {
  // Numbers passed from the client.
  const firstNumber = request.data.firstNumber;
  const secondNumber = request.data.secondNumber;

  // Checking that attributes are present and are numbers.
  if (!Number.isFinite(firstNumber) || !Number.isFinite(secondNumber)) {
    // Throwing an HttpsError so that the client gets the error details.
    throw new HttpsError("invalid-argument", "The function must be called " +
            "with two arguments \"firstNumber\" and \"secondNumber\" which " +
            "must both be numbers.");
  }

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

Jusqu'à ce que Cloud Functions v2 prenne en charge les URL cloudfunctions.net, vous devrez utiliser un initialiseur différent dans votre code client. Plutôt que de fournir un nom de fonction, fournissez une URL complète vers le SDK client. L'URL de votre fonction est imprimée à la fin d'une commande de firebase deploy réussie :

Function URL (shoulddance(us-west1)): https://shoulddance-uvb3o4q2mq-uw.a.run.app

Les callables présentent ces principales différences 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 déclencheur functions.https.onCall désérialise automatiquement le corps de la requête et valide les jetons d'authentification.

Le SDK Firebase pour Cloud Functions v2 et les versions ultérieures interagissent avec ces versions minimales du SDK client Firebase pour prendre en charge les fonctions HTTPS Callable :

  • SDK Firebase pour les plates-formes Apple 9.6.0
  • SDK Firebase pour Android 20.1.1
  • SDK Web modulaire Firebase v. 9.7.0

Si vous souhaitez ajouter des fonctionnalités similaires à une application créée sur une plate-forme non prise en charge, consultez la spécification de protocole pour https.onCall . Le reste de ce guide fournit des instructions sur la manière 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 la méthode onCall du sous-package functions/v2/https pour créer une fonction appelable HTTP. Cette méthode prend un paramètre d' event avec les propriétés data , auth , app et instanceToken :

// Saves a message to the Firebase Realtime Database but sanitizes the
// text by removing swearwords.
exports.addmessage = onCall((request) => {
  // ...
});

Pour une fonction appelable qui enregistre un message texte dans la base de données en temps réel, par exemple, data peut contenir le texte du message, ainsi que les informations d'authentification dans auth :

// Message text passed from the client.
const text = request.data.text;
// Authentication / user information is automatically added to the request.
const uid = request.auth.uid;
const name = request.auth.token.name || null;
const picture = request.auth.token.picture || null;
const email = request.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, envisagez de spécifier l' emplacement de la fonction, le cas échéant, et assurez-vous d'aligner l'emplacement de l'appelable avec l'emplacement défini lorsque vous initialisez le SDK côté client.

Si vous le souhaitez, vous pouvez joindre une attestation App Check pour protéger vos ressources backend contre les abus, tels que la fraude à la facturation ou le phishing. Voir Activer l'application de la vérification des applications pour Cloud Functions .

Renvoyer le 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 message.

return getDatabase().ref("/messages").push({
  text: sanitizedMessage,
  author: {uid, name, picture, email},
}).then(() => {
  logger.info("New Message written");
  // Returning the sanitized message to the client.
  return {text: sanitizedMessage};
})

Gérer les erreurs

Pour vous assurer que le client obtient des détails d'erreur utiles, renvoyez les erreurs d'un appelable en lançant (ou en renvoyant une Promise rejetée avec) une instance de functions.https.HttpsError . L'erreur a un attribut de code qui peut être l'une des valeurs répertoriées dans functions.https.HttpsError . Les erreurs ont également une chaîne message , qui est par défaut une chaîne vide. Ils peuvent également avoir un champ de details facultatif avec une valeur arbitraire. Si une erreur autre que HttpsError est générée par vos fonctions, votre client reçoit à la place 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 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 (!request.auth) {
  // Throwing an HttpsError so that the client gets the error details.
  throw new HttpsError("failed-precondition", "The function must be " +
          "called while authenticated.");
}

Déployer la fonction appelable

Après avoir enregistré une fonction appelable terminée dans index.js , elle est déployée avec toutes les autres fonctions lorsque vous exécutez firebase deploy . Pour déployer uniquement l'appelable, utilisez l'argument --only comme indiqué pour effectuer des déploiements partiels :

firebase deploy --only functions:addMessage

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

Configurer votre environnement de développement client

Assurez-vous de respecter 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 Apple .

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

  1. Dans Xcode, avec votre projet d'application ouvert, accédez à File > Add Packages .
  2. Lorsque vous y êtes invité, ajoutez le dépôt du SDK des plates-formes Apple Firebase :
  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 depuis votre terminal :
    npm install firebase@9.10.0 --save
    
  2. Exigez manuellement à la fois le cœur de Firebase 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);
    

Java

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

  2. Dans le fichier Gradle de votre module (au niveau de l'application) (généralement <project>/<app-module>/build.gradle ), ajoutez la dépendance pour la bibliothèque Android Cloud Functions. Nous vous recommandons d'utiliser Firebase Android BoM pour contrôler la gestion des versions de la bibliothèque.

    dependencies {
        // Import the BoM for the Firebase platform
        implementation platform('com.google.firebase:firebase-bom:30.5.0')
    
        // Add 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 Firebase Android BoM , votre application utilisera toujours des versions compatibles des bibliothèques Firebase Android.

    (Alternative) Ajouter des dépendances à la bibliothèque Firebase sans utiliser le BoM

    Si vous choisissez de ne pas utiliser la nomenclature 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 vivement d'utiliser la BoM pour gérer les versions de bibliothèque, ce qui garantit que toutes les versions sont compatibles.

    dependencies {
        // Add 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.1.1'
    }
    

Kotlin+KTX

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

  2. Dans le fichier Gradle de votre module (au niveau de l'application) (généralement <project>/<app-module>/build.gradle ), ajoutez la dépendance pour la bibliothèque Android Cloud Functions. Nous vous recommandons d'utiliser Firebase Android BoM pour contrôler la gestion des versions de la bibliothèque.

    dependencies {
        // Import the BoM for the Firebase platform
        implementation platform('com.google.firebase:firebase-bom:30.5.0')
    
        // Add 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 Firebase Android BoM , votre application utilisera toujours des versions compatibles des bibliothèques Firebase Android.

    (Alternative) Ajouter des dépendances à la bibliothèque Firebase sans utiliser le BoM

    Si vous choisissez de ne pas utiliser la nomenclature 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 vivement d'utiliser la BoM pour gérer les versions de bibliothèque, ce qui garantit que toutes les versions sont compatibles.

    dependencies {
        // Add 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.1.1'
    }
    

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

Appelez la fonction

Rapide

let addMessageURL = URL(string: "https://addmessage-xyz1234-uc.a.run.app/addMessage")!

functions.httpsCallable(addMessageURL).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
  }
}

Web version 9

import { getFunctions, httpsCallableFromURL } from 'firebase/functions';

const functions = getFunctions();
const addMessage = httpsCallableFromURL(
  functions,
  // the URL of the function
  "https://addmessage-xyz1234-uc.a.run.app/addMessage"
);

addMessage({ text: messageText })
  .then((result) => {
    // Read result of the Cloud Function.
    const data = result.data;
    const sanitizedMessage = data.text;
  });

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
            // The URL of the function
            .getHttpsCallableFromUrl(URL("https://addmessage-xyz1234-uc.a.run.app/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
            }
}

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 le code d'erreur , le message et details de l'erreur de serveur. Sinon, l'erreur contient le message INTERNAL et le code INTERNAL . Consultez les conseils pour savoir comment 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]
  }
  // ...
}

Web version 9

import { getFunctions, httpsCallableFromURL } from "firebase/functions";

const functions = getFunctions();
const addMessage = httpsCallableFromURL(
  functions,
  // the URL of the function
  "https://addmessage-xyz1234-uc.a.run.app/addMessage"
);

addMessage({ text: messageText })
  .then((result) => {
    // Read result of the Cloud Function.
    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;
    // ...
  });

Kotlin+KTX

addMessage(inputMessage)
    .addOnCompleteListener { task ->
        if (!task.isSuccessful) {
            val e = task.exception
            if (e is FirebaseFunctionsException) {
                val code = e.code
                val details = e.details
            }
        }
    }

Avant de lancer votre application, vous devez activer App Check pour vous assurer que seules vos applications peuvent accéder à vos points de terminaison de fonction appelables.