Cette page a été traduite par l'API Cloud Translation.
Switch to English

Appeler des fonctions depuis votre application

Les SDK clients Cloud Functions for Firebase vous permettent d'appeler des fonctions directement à partir d'une application Firebase. Pour appeler une fonction à partir de 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 à partir de votre application.

Il est important de garder à l'esprit que les fonctions appelables HTTPS sont similaires mais pas identiques aux fonctions HTTP. Pour utiliser les fonctions appelables HTTPS, vous devez utiliser le SDK client de votre plateforme avec l'API backend functions.https (ou implémenter le protocole). Les callables ont ces principales différences par rapport aux fonctions HTTP:

  • Avec les callables, l'authentification Firebase et les jetons FCM, 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 v0.9.1 et versions ultérieures interagit avec ces versions minimales du SDK client Firebase pour prendre en charge les fonctions appelables HTTPS:

  • SDK Firebase pour iOS 6.33.0
  • SDK Firebase pour Android 19.1.0
  • SDK JavaScript Firebase 7.21.0

Si vous souhaitez ajouter des fonctionnalités similaires à une application https.onCall 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 façon d'écrire, de déployer et d'appeler une fonction appelable HTTPS pour iOS, Android, Web, C ++ et Unity.

Écrire et déployer la fonction appelable

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

// 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 dans la base de données en temps réel, par exemple, les data peuvent contenir le texte du message, tandis que les paramètres context représentent les informations d'authentification de l'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, 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.

Renvoyer le résultat

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

// 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 du texte filtré 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 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 promesse 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 un message chaîne, qui par défaut est une chaîne vide. Ils peuvent également avoir un champ de details facultatif avec une valeur arbitraire. Si une erreur autre que HttpsError est levée depuis 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 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

Une fois que vous avez enregistré une fonction appelable terminée dans index.js , elle est déployée avec toutes les autres fonctions lorsque vous exécutez le 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 remplir toutes les conditions préalables, puis ajoutez les dépendances et bibliothèques clientes requises à votre application.

iOS

  1. Suivez les instructions pour ajouter Firebase à votre application iOS .
  2. Ajoutez le pod Cloud Functions à votre Podfile :
    pod 'Firebase/Functions'
  3. Enregistrez le fichier, puis exécutez:
    pod install

la toile

  1. Suivez les instructions pour ajouter Firebase à votre application Web .
  2. Ajoutez les bibliothèques client Firebase Core et Cloud Functions à votre application:
    <script src="https://www.gstatic.com/firebasejs/7.21.0/firebase.js"></script>
    <script src="https://www.gstatic.com/firebasejs/7.21.0/firebase-functions.js"></script>
    

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

  1. Exécutez la commande suivante depuis votre terminal:
    npm install firebase@7.21.0 --save
    
  2. Nécessite manuellement les fonctions Firebase Core et Cloud Functions:
    const firebase = require("firebase");
    // Required for side-effects
    require("firebase/functions");
    

Java

  1. Suivez les instructions pour ajouter Firebase à votre application Android .
  2. Dans votre fichier build.gradle niveau du build.gradle , assurez-vous d'inclure le référentiel Maven de Google dans vos sections buildscript et allprojects .
  3. Ajoutez la dépendance de la bibliothèque Android Cloud Functions à votre module (au niveau de l'application) Fichier Gradle (généralement app/build.gradle ):
    implementation 'com.google.firebase:firebase-functions:19.1.0'
    

Kotlin + KTX

  1. Suivez les instructions pour ajouter Firebase à votre application Android .
  2. Dans votre fichier build.gradle niveau du build.gradle , assurez-vous d'inclure le référentiel Maven de Google dans vos sections buildscript et allprojects .
  3. Ajoutez la dépendance de la bibliothèque Android Cloud Functions à votre module (au niveau de l'application) Fichier Gradle (généralement app/build.gradle ):
    implementation 'com.google.firebase:firebase-functions:19.1.0'
    

C ++

Pour C ++ avec Android :

  1. Suivez les instructions pour ajouter Firebase à votre projet C ++ .
  2. Dans votre fichier build.gradle niveau du build.gradle , assurez-vous d'inclure le référentiel Maven de Google dans vos sections buildscript et allprojects .
  3. Ajoutez la bibliothèque firebase_functions à votre fichier CMakeLists.txt .

Pour C ++ avec iOS :

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

Unité

  1. Suivez les instructions pour ajouter Firebase à votre projet Unity .
  2. Ajoutez le FirebaseFunctions.unitypackage du SDK Firebase Unity à 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];

la toile

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

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 text = (result?.data as? [String: Any])?["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"];
}];

la toile

var addMessage = firebase.functions().httpsCallable('addMessage');
addMessage({text: messageText}).then(function(result) {
  // Read result of the Cloud Function.
  var sanitizedMessage = result.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 émis 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 erreur, le message et les details de l'erreur du serveur. Sinon, l'erreur contient le message INTERNAL et le code INTERNAL . Consultez les instructions 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]
  }
  // ...
}

Objectif c

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

la toile

var addMessage = firebase.functions().httpsCallable('addMessage');
addMessage({text: messageText}).then(function(result) {
  // Read result of the Cloud Function.
  var sanitizedMessage = result.data.text;
}).catch(function(error) {
  // Getting the Error details.
  var code = error.code;
  var message = error.message;
  var 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;
  }
});