Llama a funciones desde tu app


Los SDK de cliente de Cloud Functions para Firebase te permiten llamar funciones directamente desde una aplicación de Firebase. Para llamar una función desde su aplicación de esta manera, escriba e implemente una función HTTP invocable en Cloud Functions y luego agregue lógica de cliente para llamar la función desde su aplicación.

Es importante tener en cuenta que las funciones invocables HTTP son similares pero no idénticas a las funciones HTTP. Para utilizar funciones invocables HTTP, debe utilizar el SDK del cliente para su plataforma junto con la API de backend (o implementar el protocolo). Los callables tienen estas diferencias clave con las funciones HTTP:

  • Con los callables, los tokens de Firebase Authentication, los tokens de FCM y los tokens de App Check, cuando están disponibles, se incluyen automáticamente en las solicitudes.
  • El desencadenador deserializa automáticamente el cuerpo de la solicitud y valida los tokens de autenticación.

El SDK de Firebase para Cloud Functions de segunda generación y superiores interopera con estas versiones mínimas del SDK de cliente de Firebase para admitir funciones invocables HTTPS:

  • SDK de Firebase para plataformas Apple 10.19.0
  • SDK de Firebase para Android 20.4.0
  • SDK web modular de Firebase versión 9.7.0

Si desea agregar una funcionalidad similar a una aplicación creada en una plataforma no compatible, consulte la Especificación de protocolo para https.onCall . El resto de esta guía proporciona instrucciones sobre cómo escribir, implementar y llamar a una función invocable HTTP para plataformas Apple, Android, web, C++ y Unity.

Escribir e implementar la función invocable

Utilice functions.https.onCall para crear una función invocable HTTPS. Este método toma dos parámetros: data y context opcional:

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

Para una función invocable que guarda un mensaje de texto en Realtime Database, por ejemplo, data podrían contener el texto del mensaje, mientras que los parámetros context representan información de autenticación del usuario:

// 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 distancia entre la ubicación de la función invocable y la ubicación del cliente que llama puede crear latencia en la red. Para optimizar el rendimiento, considere especificar la ubicación de la función cuando corresponda y asegúrese de alinear la ubicación del invocable con la ubicación establecida cuando inicializa el SDK en el lado del cliente.

Opcionalmente, puede adjuntar una certificación de App Check para ayudar a proteger sus recursos de backend contra abusos, como fraude de facturación o phishing. Consulte Habilitar la aplicación de App Check para funciones en la nube .

Devolviendo el resultado

Para enviar datos al cliente, devuelva datos que puedan codificarse en JSON. Por ejemplo, para devolver el resultado de una operación de suma:

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

Para devolver datos después de una operación asincrónica, devuelva una promesa. Los datos devueltos por la promesa se devuelven al cliente. Por ejemplo, podría devolver texto desinfectado que la función invocable escribió en la base de datos en tiempo real:

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

Manejar errores

Para garantizar que el cliente obtenga detalles útiles del error, devuelva errores de un invocable lanzando (o devolviendo una Promesa rechazada con) una instancia de functions.https.HttpsError . El error tiene un atributo code que puede ser uno de los valores enumerados en functions.https.HttpsError . Los errores también tienen una cadena message , que por defecto es una cadena vacía. También pueden tener un campo details opcional con un valor arbitrario. Si sus funciones arrojan un error distinto de HttpsError , su cliente recibe un error con el mensaje INTERNAL y el código internal .

Por ejemplo, una función podría generar errores de validación y autenticación de datos con mensajes de error para devolver al cliente que llama:

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

Implementar la función invocable

Después de guardar una función invocable completa dentro de index.js , se implementa junto con todas las demás funciones cuando ejecuta firebase deploy . Para implementar solo lo invocable, use el argumento --only como se muestra para realizar implementaciones parciales :

firebase deploy --only functions:addMessage

Si encuentra errores de permisos al implementar funciones, asegúrese de que se asignen las funciones de IAM adecuadas al usuario que ejecuta los comandos de implementación.

Configure el entorno de desarrollo de su cliente

Asegúrese de cumplir con los requisitos previos y luego agregue las dependencias y bibliotecas cliente requeridas a su aplicación.

iOS+

Sigue las instrucciones para agregar Firebase a tu aplicación de Apple .

Utilice Swift Package Manager para instalar y administrar las dependencias de Firebase.

  1. En Xcode, con el proyecto de su aplicación abierto, navegue hasta Archivo > Agregar paquetes .
  2. Cuando se le solicite, agregue el repositorio SDK de las plataformas Firebase Apple:
  3.   https://github.com/firebase/firebase-ios-sdk.git
  4. Elija la biblioteca de Cloud Functions.
  5. Agregue el indicador -ObjC a la sección Otros indicadores del vinculador de la configuración de compilación de su objetivo.
  6. Cuando termine, Xcode comenzará automáticamente a resolver y descargar sus dependencias en segundo plano.

API modular web

  1. Siga las instrucciones para agregar Firebase a su aplicación web . Asegúrese de ejecutar el siguiente comando desde su terminal:
    npm install firebase@10.7.1 --save
    
  2. Requiere manualmente tanto Firebase core como 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);
    

API con espacio de nombres web

  1. Siga las instrucciones para agregar Firebase a su aplicación web .
  2. Agregue las bibliotecas cliente de Firebase core y Cloud Functions a su aplicación:
    <script src="https://www.gstatic.com/firebasejs/8.10.1/firebase.js"></script>
    <script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-functions.js"></script>
    

El SDK de Cloud Functions también está disponible como paquete npm.

  1. Ejecute el siguiente comando desde su terminal:
    npm install firebase@8.10.1 --save
    
  2. Requiere manualmente tanto Firebase core como Cloud Functions:
    const firebase = require("firebase");
    // Required for side-effects
    require("firebase/functions");
    

Kotlin+KTX

  1. Siga las instrucciones para agregar Firebase a su aplicación de Android .

  2. En el archivo Gradle de su módulo (nivel de aplicación) (generalmente <project>/<app-module>/build.gradle.kts o <project>/<app-module>/build.gradle ), agregue la dependencia para Cloud Functions biblioteca para Android. Recomendamos utilizar Firebase Android BoM para controlar el control de versiones de la biblioteca.

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

    Al usar Firebase Android BoM , su aplicación siempre usará versiones compatibles de las bibliotecas de Firebase Android.

    (Alternativa) Agregue dependencias de la biblioteca de Firebase sin usar la BoM

    Si elige no utilizar la BoM de Firebase, debe especificar cada versión de la biblioteca de Firebase en su línea de dependencia.

    Tenga en cuenta que si usa varias bibliotecas de Firebase en su aplicación, le recomendamos encarecidamente usar la BoM para administrar las versiones de la biblioteca, lo que garantiza que todas las versiones sean 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.4.0")
    }
    
    ¿Busca un módulo de biblioteca específico de Kotlin? A partir de octubre de 2023 (Firebase BoM 32.5.0) , tanto los desarrolladores de Kotlin como los de Java podrán depender del módulo de biblioteca principal (para más detalles, consulte las preguntas frecuentes sobre esta iniciativa ).

Java

  1. Siga las instrucciones para agregar Firebase a su aplicación de Android .

  2. En el archivo Gradle de su módulo (nivel de aplicación) (generalmente <project>/<app-module>/build.gradle.kts o <project>/<app-module>/build.gradle ), agregue la dependencia para Cloud Functions biblioteca para Android. Recomendamos utilizar Firebase Android BoM para controlar el control de versiones de la biblioteca.

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

    Al usar Firebase Android BoM , su aplicación siempre usará versiones compatibles de las bibliotecas de Firebase Android.

    (Alternativa) Agregue dependencias de la biblioteca de Firebase sin usar la BoM

    Si elige no utilizar la BoM de Firebase, debe especificar cada versión de la biblioteca de Firebase en su línea de dependencia.

    Tenga en cuenta que si usa varias bibliotecas de Firebase en su aplicación, le recomendamos encarecidamente usar la BoM para administrar las versiones de la biblioteca, lo que garantiza que todas las versiones sean 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.4.0")
    }
    
    ¿Busca un módulo de biblioteca específico de Kotlin? A partir de octubre de 2023 (Firebase BoM 32.5.0) , tanto los desarrolladores de Kotlin como los de Java podrán depender del módulo de biblioteca principal (para más detalles, consulte las preguntas frecuentes sobre esta iniciativa ).

Dart

  1. Sigue las instrucciones para agregar Firebase a tu aplicación Flutter .

  2. Desde la raíz de su proyecto Flutter, ejecute el siguiente comando para instalar el complemento:

    flutter pub add cloud_functions
    
  3. Una vez completado, reconstruya su aplicación Flutter:

    flutter run
    
  4. Una vez instalado, puede acceder al complemento cloud_functions importándolo en su código Dart:

    import 'package:cloud_functions/cloud_functions.dart';
    

C++

Para C++ con Android :

  1. Siga las instrucciones para agregar Firebase a su proyecto C++ .
  2. Agregue la biblioteca firebase_functions a su archivo CMakeLists.txt .

Para C++ con plataformas Apple :

  1. Siga las instrucciones para agregar Firebase a su proyecto C++ .
  2. Agregue el pod de Cloud Functions a su Podfile :
    pod 'Firebase/Functions'
  3. Guarde el archivo y luego ejecute:
    pod install
  4. Agregue los marcos Firebase core y Cloud Functions del SDK de Firebase C++ a su proyecto Xcode.
    • firebase.framework
    • firebase_functions.framework

Unidad

  1. Siga las instrucciones para agregar Firebase a su proyecto de Unity .
  2. Agregue el FirebaseFunctions.unitypackage del SDK de Firebase Unity a su proyecto de Unity.

Inicializar el SDK del cliente

Inicialice una instancia de Cloud Functions:

Rápido

lazy var functions = Functions.functions()

C objetivo

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

API con espacio de nombres web

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

API modular web

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

Kotlin+KTX

private lateinit var functions: FirebaseFunctions
// ...
functions = Firebase.functions

Java

private FirebaseFunctions mFunctions;
// ...
mFunctions = FirebaseFunctions.getInstance();

Dart

final functions = FirebaseFunctions.instance;

C++

firebase::functions::Functions* functions;
// ...
functions = firebase::functions::Functions::GetInstance(app);

Unidad

functions = Firebase.Functions.DefaultInstance;

Llame a la función

Rápido

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

C objetivo

[[_functions HTTPSCallableWithName:@"addMessage"] callWithObject:@{@"text": _inputField.text}
                                                      completion:^(FIRHTTPSCallableResult * _Nullable result, NSError * _Nullable error) {
  if (error) {
    if ([error.domain isEqual:@"com.firebase.functions"]) {
      FIRFunctionsErrorCode code = error.code;
      NSString *message = error.localizedDescription;
      NSObject *details = error.userInfo[@"details"];
    }
    // ...
  }
  self->_resultField.text = result.data[@"text"];
}];

API con espacio de nombres web

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

API modular web

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

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

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

Dart

    final result = await FirebaseFunctions.instance.httpsCallable('addMessage').call(
      {
        "text": text,
        "push": true,
      },
    );
    _response = result.data as String;

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

Unidad

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

Manejar errores en el cliente.

El cliente recibe un error si el servidor arrojó un error o si la promesa resultante fue rechazada.

Si el error devuelto por la función es de tipo function.https.HttpsError , entonces el cliente recibe el code de error, message y details del error del servidor. De lo contrario, el error contiene el mensaje INTERNAL y el código INTERNAL . Consulte la guía sobre cómo manejar errores en su función invocable.

Rápido

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

C objetivo

if (error) {
  if ([error.domain isEqual:@"com.firebase.functions"]) {
    FIRFunctionsErrorCode code = error.code;
    NSString *message = error.localizedDescription;
    NSObject *details = error.userInfo[@"details"];
  }
  // ...
}

API con espacio de nombres web

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

API modular web

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

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

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

Dart

try {
  final result =
      await FirebaseFunctions.instance.httpsCallable('addMessage').call();
} on FirebaseFunctionsException catch (error) {
  print(error.code);
  print(error.details);
  print(error.message);
}

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

Unidad

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

Antes de iniciar su aplicación, debe habilitar App Check para ayudar a garantizar que solo sus aplicaciones puedan acceder a sus puntos finales de funciones invocables.

,


Los SDK de cliente de Cloud Functions para Firebase te permiten llamar funciones directamente desde una aplicación de Firebase. Para llamar una función desde su aplicación de esta manera, escriba e implemente una función HTTP invocable en Cloud Functions y luego agregue lógica de cliente para llamar la función desde su aplicación.

Es importante tener en cuenta que las funciones invocables HTTP son similares pero no idénticas a las funciones HTTP. Para utilizar funciones invocables HTTP, debe utilizar el SDK del cliente para su plataforma junto con la API de backend (o implementar el protocolo). Los callables tienen estas diferencias clave con las funciones HTTP:

  • Con los callables, los tokens de Firebase Authentication, los tokens de FCM y los tokens de App Check, cuando están disponibles, se incluyen automáticamente en las solicitudes.
  • El desencadenador deserializa automáticamente el cuerpo de la solicitud y valida los tokens de autenticación.

El SDK de Firebase para Cloud Functions de segunda generación y superiores interopera con estas versiones mínimas del SDK de cliente de Firebase para admitir funciones invocables HTTPS:

  • SDK de Firebase para plataformas Apple 10.19.0
  • SDK de Firebase para Android 20.4.0
  • SDK web modular de Firebase versión 9.7.0

Si desea agregar una funcionalidad similar a una aplicación creada en una plataforma no compatible, consulte la Especificación de protocolo para https.onCall . El resto de esta guía proporciona instrucciones sobre cómo escribir, implementar y llamar a una función invocable HTTP para plataformas Apple, Android, web, C++ y Unity.

Escribir e implementar la función invocable

Utilice functions.https.onCall para crear una función invocable HTTPS. Este método toma dos parámetros: data y context opcional:

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

Para una función invocable que guarda un mensaje de texto en Realtime Database, por ejemplo, data podrían contener el texto del mensaje, mientras que los parámetros context representan información de autenticación del usuario:

// 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 distancia entre la ubicación de la función invocable y la ubicación del cliente que llama puede crear latencia en la red. Para optimizar el rendimiento, considere especificar la ubicación de la función cuando corresponda y asegúrese de alinear la ubicación del invocable con la ubicación establecida cuando inicializa el SDK en el lado del cliente.

Opcionalmente, puede adjuntar una certificación de App Check para ayudar a proteger sus recursos de backend contra abusos, como fraude de facturación o phishing. Consulte Habilitar la aplicación de App Check para funciones en la nube .

Devolviendo el resultado

Para enviar datos al cliente, devuelva datos que puedan codificarse en JSON. Por ejemplo, para devolver el resultado de una operación de suma:

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

Para devolver datos después de una operación asincrónica, devuelva una promesa. Los datos devueltos por la promesa se devuelven al cliente. Por ejemplo, podría devolver texto desinfectado que la función invocable escribió en la base de datos en tiempo real:

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

Manejar errores

Para garantizar que el cliente obtenga detalles útiles del error, devuelva errores de un invocable lanzando (o devolviendo una Promesa rechazada con) una instancia de functions.https.HttpsError . El error tiene un atributo code que puede ser uno de los valores enumerados en functions.https.HttpsError . Los errores también tienen una cadena message , que por defecto es una cadena vacía. También pueden tener un campo details opcional con un valor arbitrario. Si sus funciones arrojan un error distinto de HttpsError , su cliente recibe un error con el mensaje INTERNAL y el código internal .

Por ejemplo, una función podría generar errores de validación y autenticación de datos con mensajes de error para devolver al cliente que llama:

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

Implementar la función invocable

Después de guardar una función invocable completa dentro de index.js , se implementa junto con todas las demás funciones cuando ejecuta firebase deploy . Para implementar solo lo invocable, use el argumento --only como se muestra para realizar implementaciones parciales :

firebase deploy --only functions:addMessage

Si encuentra errores de permisos al implementar funciones, asegúrese de que se asignen las funciones de IAM adecuadas al usuario que ejecuta los comandos de implementación.

Configure el entorno de desarrollo de su cliente

Asegúrese de cumplir con los requisitos previos y luego agregue las dependencias y bibliotecas cliente requeridas a su aplicación.

iOS+

Sigue las instrucciones para agregar Firebase a tu aplicación de Apple .

Utilice Swift Package Manager para instalar y administrar las dependencias de Firebase.

  1. En Xcode, con el proyecto de su aplicación abierto, navegue hasta Archivo > Agregar paquetes .
  2. Cuando se le solicite, agregue el repositorio SDK de las plataformas Firebase Apple:
  3.   https://github.com/firebase/firebase-ios-sdk.git
  4. Elija la biblioteca de Cloud Functions.
  5. Agregue el indicador -ObjC a la sección Otros indicadores del vinculador de la configuración de compilación de su objetivo.
  6. Cuando termine, Xcode comenzará automáticamente a resolver y descargar sus dependencias en segundo plano.

API modular web

  1. Siga las instrucciones para agregar Firebase a su aplicación web . Asegúrese de ejecutar el siguiente comando desde su terminal:
    npm install firebase@10.7.1 --save
    
  2. Requiere manualmente tanto Firebase core como 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);
    

API con espacio de nombres web

  1. Siga las instrucciones para agregar Firebase a su aplicación web .
  2. Agregue las bibliotecas cliente de Firebase core y Cloud Functions a su aplicación:
    <script src="https://www.gstatic.com/firebasejs/8.10.1/firebase.js"></script>
    <script src="https://www.gstatic.com/firebasejs/8.10.1/firebase-functions.js"></script>
    

El SDK de Cloud Functions también está disponible como paquete npm.

  1. Ejecute el siguiente comando desde su terminal:
    npm install firebase@8.10.1 --save
    
  2. Requiere manualmente tanto Firebase core como Cloud Functions:
    const firebase = require("firebase");
    // Required for side-effects
    require("firebase/functions");
    

Kotlin+KTX

  1. Siga las instrucciones para agregar Firebase a su aplicación de Android .

  2. En el archivo Gradle de su módulo (nivel de aplicación) (generalmente <project>/<app-module>/build.gradle.kts o <project>/<app-module>/build.gradle ), agregue la dependencia para Cloud Functions biblioteca para Android. Recomendamos utilizar Firebase Android BoM para controlar el control de versiones de la biblioteca.

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

    Al usar Firebase Android BoM , su aplicación siempre usará versiones compatibles de las bibliotecas de Firebase Android.

    (Alternativa) Agregue dependencias de la biblioteca de Firebase sin usar la BoM

    Si elige no utilizar la BoM de Firebase, debe especificar cada versión de la biblioteca de Firebase en su línea de dependencia.

    Tenga en cuenta que si usa varias bibliotecas de Firebase en su aplicación, le recomendamos encarecidamente usar la BoM para administrar las versiones de la biblioteca, lo que garantiza que todas las versiones sean 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.4.0")
    }
    
    ¿Busca un módulo de biblioteca específico de Kotlin? A partir de octubre de 2023 (Firebase BoM 32.5.0) , tanto los desarrolladores de Kotlin como los de Java podrán depender del módulo de biblioteca principal (para más detalles, consulte las preguntas frecuentes sobre esta iniciativa ).

Java

  1. Siga las instrucciones para agregar Firebase a su aplicación de Android .

  2. En el archivo Gradle de su módulo (nivel de aplicación) (generalmente <project>/<app-module>/build.gradle.kts o <project>/<app-module>/build.gradle ), agregue la dependencia para Cloud Functions biblioteca para Android. Recomendamos utilizar Firebase Android BoM para controlar el control de versiones de la biblioteca.

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

    Al usar Firebase Android BoM , su aplicación siempre usará versiones compatibles de las bibliotecas de Firebase Android.

    (Alternativa) Agregue dependencias de la biblioteca de Firebase sin usar la BoM

    Si elige no utilizar la BoM de Firebase, debe especificar cada versión de la biblioteca de Firebase en su línea de dependencia.

    Tenga en cuenta que si usa varias bibliotecas de Firebase en su aplicación, le recomendamos encarecidamente usar la BoM para administrar las versiones de la biblioteca, lo que garantiza que todas las versiones sean 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.4.0")
    }
    
    ¿Busca un módulo de biblioteca específico de Kotlin? A partir de octubre de 2023 (Firebase BoM 32.5.0) , tanto los desarrolladores de Kotlin como los de Java podrán depender del módulo de biblioteca principal (para más detalles, consulte las preguntas frecuentes sobre esta iniciativa ).

Dart

  1. Sigue las instrucciones para agregar Firebase a tu aplicación Flutter .

  2. Desde la raíz de su proyecto Flutter, ejecute el siguiente comando para instalar el complemento:

    flutter pub add cloud_functions
    
  3. Una vez completado, reconstruya su aplicación Flutter:

    flutter run
    
  4. Una vez instalado, puede acceder al complemento cloud_functions importándolo en su código Dart:

    import 'package:cloud_functions/cloud_functions.dart';
    

C++

Para C++ con Android :

  1. Siga las instrucciones para agregar Firebase a su proyecto C++ .
  2. Agregue la biblioteca firebase_functions a su archivo CMakeLists.txt .

Para C++ con plataformas Apple :

  1. Siga las instrucciones para agregar Firebase a su proyecto C++ .
  2. Agregue el pod de Cloud Functions a su Podfile :
    pod 'Firebase/Functions'
  3. Guarde el archivo y luego ejecute:
    pod install
  4. Agregue los marcos Firebase core y Cloud Functions del SDK de Firebase C++ a su proyecto Xcode.
    • firebase.framework
    • firebase_functions.framework

Unidad

  1. Siga las instrucciones para agregar Firebase a su proyecto de Unity .
  2. Agregue el FirebaseFunctions.unitypackage del SDK de Firebase Unity a su proyecto de Unity.

Inicializar el SDK del cliente

Inicialice una instancia de Cloud Functions:

Rápido

lazy var functions = Functions.functions()

C objetivo

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

API con espacio de nombres web

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

API modular web

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

Kotlin+KTX

private lateinit var functions: FirebaseFunctions
// ...
functions = Firebase.functions

Java

private FirebaseFunctions mFunctions;
// ...
mFunctions = FirebaseFunctions.getInstance();

Dart

final functions = FirebaseFunctions.instance;

C++

firebase::functions::Functions* functions;
// ...
functions = firebase::functions::Functions::GetInstance(app);

Unidad

functions = Firebase.Functions.DefaultInstance;

Llame a la función

Rápido

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

C objetivo

[[_functions HTTPSCallableWithName:@"addMessage"] callWithObject:@{@"text": _inputField.text}
                                                      completion:^(FIRHTTPSCallableResult * _Nullable result, NSError * _Nullable error) {
  if (error) {
    if ([error.domain isEqual:@"com.firebase.functions"]) {
      FIRFunctionsErrorCode code = error.code;
      NSString *message = error.localizedDescription;
      NSObject *details = error.userInfo[@"details"];
    }
    // ...
  }
  self->_resultField.text = result.data[@"text"];
}];

API con espacio de nombres web

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

API modular web

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

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

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

Dart

    final result = await FirebaseFunctions.instance.httpsCallable('addMessage').call(
      {
        "text": text,
        "push": true,
      },
    );
    _response = result.data as String;

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

Unidad

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

Manejar errores en el cliente.

El cliente recibe un error si el servidor arrojó un error o si la promesa resultante fue rechazada.

Si el error devuelto por la función es de tipo function.https.HttpsError , entonces el cliente recibe el code de error, message y details del error del servidor. De lo contrario, el error contiene el mensaje INTERNAL y el código INTERNAL . Consulte la guía sobre cómo manejar errores en su función invocable.

Rápido

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

C objetivo

if (error) {
  if ([error.domain isEqual:@"com.firebase.functions"]) {
    FIRFunctionsErrorCode code = error.code;
    NSString *message = error.localizedDescription;
    NSObject *details = error.userInfo[@"details"];
  }
  // ...
}

API con espacio de nombres web

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

API modular web

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

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

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

Dart

try {
  final result =
      await FirebaseFunctions.instance.httpsCallable('addMessage').call();
} on FirebaseFunctionsException catch (error) {
  print(error.code);
  print(error.details);
  print(error.message);
}

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

Unidad

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

Antes de iniciar su aplicación, debe habilitar App Check para ayudar a garantizar que solo sus aplicaciones puedan acceder a sus puntos finales de funciones invocables.