Primeros pasos: Escribe, prueba e implementa tus primeras funciones


Para comenzar a usar Cloud Functions, sigue este instructivo, que comienza con las tareas de configuración obligatorias y, luego, te indica los pasos para crear, probar e implementar dos funciones relacionadas:

  • Una función “agregar mensaje” que expone una URL que acepta un valor de texto y lo escribe en Cloud Firestore.
  • Una función “convertir a mayúsculas” que se activa cuando se escribe en Cloud Firestore y aplica mayúsculas al texto.

Este es el código de muestra completo que contiene las funciones:

Node.js

// The Cloud Functions for Firebase SDK to create Cloud Functions and triggers.
const {logger} = require("firebase-functions");
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");

// The Firebase Admin SDK to access Firestore.
const {initializeApp} = require("firebase-admin/app");
const {getFirestore} = require("firebase-admin/firestore");

initializeApp();

// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addmessage = onRequest(async (req, res) => {
  // Grab the text parameter.
  const original = req.query.text;
  // Push the new message into Firestore using the Firebase Admin SDK.
  const writeResult = await getFirestore()
      .collection("messages")
      .add({original: original});
  // Send back a message that we've successfully written the message
  res.json({result: `Message with ID: ${writeResult.id} added.`});
});

// Listens for new messages added to /messages/:documentId/original
// and saves an uppercased version of the message
// to /messages/:documentId/uppercase
exports.makeuppercase = onDocumentCreated("/messages/{documentId}", (event) => {
  // Grab the current value of what was written to Firestore.
  const original = event.data.data().original;

  // Access the parameter `{documentId}` with `event.params`
  logger.log("Uppercasing", event.params.documentId, original);

  const uppercase = original.toUpperCase();

  // You must return a Promise when performing
  // asynchronous tasks inside a function
  // such as writing to Firestore.
  // Setting an 'uppercase' field in Firestore document returns a Promise.
  return event.data.ref.set({uppercase}, {merge: true});
});

Python (vista previa)

# The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
from firebase_functions import firestore_fn, https_fn

# The Firebase Admin SDK to access Cloud Firestore.
from firebase_admin import initialize_app, firestore
import google.cloud.firestore

app = initialize_app()


@https_fn.on_request()
def addmessage(req: https_fn.Request) -> https_fn.Response:
    """Take the text parameter passed to this HTTP endpoint and insert it into
    a new document in the messages collection."""
    # Grab the text parameter.
    original = req.args.get("text")
    if original is None:
        return https_fn.Response("No text parameter provided", status=400)

    firestore_client: google.cloud.firestore.Client = firestore.client()

    # Push the new message into Cloud Firestore using the Firebase Admin SDK.
    _, doc_ref = firestore_client.collection("messages").add(
        {"original": original}
    )

    # Send back a message that we've successfully written the message
    return https_fn.Response(f"Message with ID {doc_ref.id} added.")




@firestore_fn.on_document_created(document="messages/{pushId}")
def makeuppercase(
    event: firestore_fn.Event[firestore_fn.DocumentSnapshot | None],
) -> None:
    """Listens for new documents to be added to /messages. If the document has
    an "original" field, creates an "uppercase" field containg the contents of
    "original" in upper case."""

    # Get the value of "original" if it exists.
    if event.data is None:
        return
    try:
        original = event.data.get("original")
    except KeyError:
        # No "original" field, so do nothing.
        return

    # Set the "uppercase" field.
    print(f"Uppercasing {event.params['pushId']}: {original}")
    upper = original.upper()
    event.data.reference.update({"uppercase": upper})


Acerca de este instructivo

Para esta muestra elegimos Cloud Firestore y funciones activadas por HTTP, en parte debido a que estos activadores en segundo plano pueden probarse completamente en Firebase Local Emulator Suite. Este conjunto de herramientas también es compatible con los activadores que admiten llamadas de Realtime Database, Cloud Storage, Pub/Sub, Auth y HTTP. Otros tipos de activadores en segundo plano, como Remote Config y Test Lab, se pueden probar de forma interactiva con conjuntos de herramientas que no se describen en esta página.

En las siguientes secciones de este instructivo, se detallan los pasos necesarios para compilar, probar e implementar la muestra.

Crea un proyecto de Firebase

  1. En Firebase console, haz clic en Agregar proyecto.

    • Para agregar recursos de Firebase a un proyecto existente de Google Cloud, ingresa el nombre del proyecto o selecciónalo en el menú desplegable.

    • Para crear un proyecto nuevo, ingresa el nombre que quieras. También puedes editar el ID del proyecto que aparece debajo del nombre.

  2. Si se te solicita, revisa y acepta las Condiciones de Firebase.

  3. Haz clic en Continuar.

  4. Opcional: Configura Google Analytics para tu proyecto para tener una experiencia óptima con cualquiera de los siguientes productos de Firebase:

    Selecciona una cuenta de Google Analytics existente o crea una nueva.

    Si decides crear una cuenta nueva, selecciona la ubicación de los informes de Analytics. Luego, acepta la configuración de uso compartido de datos y las condiciones de Google Analytics para el proyecto.

  5. Haz clic en Crear proyecto (o Agregar Firebase si usas un proyecto de Google Cloud existente).

Firebase aprovisiona los recursos para tu proyecto de forma automática. Cuando finalice, verás la página de descripción general del proyecto en Firebase console.

Configura tu entorno y Firebase CLI

Node.js

Para escribir funciones, necesitarás un entorno de Node.js. Además, si quieres implementarlas en el entorno de ejecución de Cloud Functions, necesitarás Firebase CLI. Te recomendamos usar Node Version Manager para instalar Node.js y npm.

Una vez que hayas instalado Node.js y npm, instala Firebase CLI con el método que prefieras. Ejecuta el siguiente comando para instalar la CLI a través de npm:

npm install -g firebase-tools

Esto instala el comando firebase disponible de manera global. Si el comando falla, tal vez tengas que cambiar los permisos de npm. Para actualizar a la versión más reciente de firebase-tools, vuelve a ejecutar el mismo comando.

Python (vista previa)

Para escribir funciones, necesitarás un entorno de Python. Además, si quieres implementarlas en el entorno de ejecución de Cloud Functions, necesitarás Firebase CLI. Te recomendamos usar venv para aislar las dependencias. Se admiten las versiones 3.10 y 3.11 de Python.

Una vez que hayas instalado Python, instala Firebase CLI con el método que prefieras.

Inicializa el proyecto

Cuando inicializas el SDK de Firebase para Cloud Functions, creas un proyecto vacío con dependencias y código de muestra mínimo. Si usas Node.js, puedes elegir TypeScript o JavaScript para redactar funciones. A los fines de este instructivo, también deberás inicializar Cloud Firestore.

Para inicializar el proyecto:

  1. Ejecuta firebase login para acceder a través del navegador y autenticar Firebase CLI.
  2. Ve al directorio del proyecto de Firebase.
  3. Ejecuta firebase init firestore. Para este instructivo, puedes aceptar los valores predeterminados cuando se te soliciten los archivos de índice y reglas de Firestore. Si aún no usas Cloud Firestore en este proyecto, también deberás seleccionar un modo y una ubicación de inicio para esta plataforma, como se describe en Primeros pasos con Cloud Firestore.
  4. Ejecuta firebase init functions. La CLI te solicitará que elijas una base de código existente o que inicialices y nombres una nueva. Cuando recién comienzas, una sola base de código en la ubicación predeterminada es adecuada. Más adelante, a medida que se expande la implementación, te recomendamos organizar funciones en bases de código.
  5. CLI te ofrece las siguientes opciones de lenguaje:

    • JavaScript
    • TypeScript
    • Python

    Para este instructivo, selecciona JavaScript o Python. Para la creación en TypeScript, consulta Escribe funciones en TypeScript.

  6. CLI te ofrece una opción para instalar dependencias. Es seguro rechazarla si quieres administrar las dependencias de otra manera.

Después de completar estos comandos de forma correcta, la estructura del proyecto será similar a la siguiente:

Node.js

myproject
+- .firebaserc    # Hidden file that helps you quickly switch between
|                 # projects with `firebase use`
|
+- firebase.json  # Describes properties for your project
|
+- functions/     # Directory containing all your functions code
      |
      +- .eslintrc.json  # Optional file containing rules for JavaScript linting.
      |
      +- package.json  # npm package file describing your Cloud Functions code
      |
      +- index.js      # Main source file for your Cloud Functions code
      |
      +- node_modules/ # Directory where your dependencies (declared in
                        # package.json) are installed

Para Node.js, el archivo package.json que se creó durante la inicialización contiene una clave importante: "engines": {"node": "18"}. Esta indica la versión de Node.js que se usará para escribir e implementar funciones. Puedes seleccionar otras versiones compatibles.

Python (vista previa)

myproject
+- .firebaserc    # Hidden file that helps you quickly switch between
|                 # projects with `firebase use`
|
+- firebase.json  # Describes properties for your project
|
+- functions/     # Directory containing all your functions code
      |
      +- main.py      # Main source file for your Cloud Functions code
      |
      +- requirements.txt  #  List of the project's modules and packages 
      |
      +- venv/ # Directory where your dependencies are installed

Importa los módulos requeridos para inicializar una app

Después de completar las tareas de configuración, puedes abrir el directorio del código fuente y comenzar a agregar código como se describe en las siguientes secciones. Para esta muestra, tu proyecto debe importar los módulos de Cloud Functions y del SDK de Admin. Agrega líneas como las siguientes al archivo fuente:

Node.js

// The Cloud Functions for Firebase SDK to create Cloud Functions and triggers.
const {logger} = require("firebase-functions");
const {onRequest} = require("firebase-functions/v2/https");
const {onDocumentCreated} = require("firebase-functions/v2/firestore");

// The Firebase Admin SDK to access Firestore.
const {initializeApp} = require("firebase-admin/app");
const {getFirestore} = require("firebase-admin/firestore");

initializeApp();

Python (vista previa)

# The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
from firebase_functions import firestore_fn, https_fn

# The Firebase Admin SDK to access Cloud Firestore.
from firebase_admin import initialize_app, firestore
import google.cloud.firestore

app = initialize_app()

Estas líneas cargan los módulos requeridos. Además, inicializan una instancia de app admin desde la cual se pueden realizar cambios de Cloud Firestore. Dondequiera que esté disponible la compatibilidad con el SDK de Admin, como sucede con FCM, Authentication y Firebase Realtime Database, esta brinda una poderosa manera de integrar Firebase en Cloud Functions.

Firebase CLI instala automáticamente los SDKs de Firebase Admin y de Firebase para los módulos de Cloud Functions cuando inicializas tu proyecto. Para obtener más información sobre cómo agregar bibliotecas de terceros al proyecto, consulta Cómo controlar dependencias.

Agrega la función “agregar mensaje”

Para la función “agregar mensaje”, agrega estas líneas al archivo fuente:

Node.js

// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addmessage = onRequest(async (req, res) => {
  // Grab the text parameter.
  const original = req.query.text;
  // Push the new message into Firestore using the Firebase Admin SDK.
  const writeResult = await getFirestore()
      .collection("messages")
      .add({original: original});
  // Send back a message that we've successfully written the message
  res.json({result: `Message with ID: ${writeResult.id} added.`});
});

Python (vista previa)

@https_fn.on_request()
def addmessage(req: https_fn.Request) -> https_fn.Response:
    """Take the text parameter passed to this HTTP endpoint and insert it into
    a new document in the messages collection."""
    # Grab the text parameter.
    original = req.args.get("text")
    if original is None:
        return https_fn.Response("No text parameter provided", status=400)

    firestore_client: google.cloud.firestore.Client = firestore.client()

    # Push the new message into Cloud Firestore using the Firebase Admin SDK.
    _, doc_ref = firestore_client.collection("messages").add(
        {"original": original}
    )

    # Send back a message that we've successfully written the message
    return https_fn.Response(f"Message with ID {doc_ref.id} added.")


La función “agregar mensaje” es un extremo de HTTP. Cada solicitud que se envía al extremo hace que los objetos Request y Response se pasen al controlador de solicitudes de tu plataforma (onRequest() o on_request).

Las funciones de HTTP son síncronas (similares a las funciones que admiten llamadas), por lo que debes enviar una respuesta lo más rápido posible y aplazar el trabajo con Cloud Firestore. La función de HTTP “agregar mensaje” transmite un valor de texto al extremo HTTP y lo inserta en la base de datos en la ruta /messages/:documentId/original.

Agrega la función “convertir a mayúsculas”

Para la función “convertir a mayúsculas”, agrega estas líneas a tu archivo fuente:

Node.js

// Listens for new messages added to /messages/:documentId/original
// and saves an uppercased version of the message
// to /messages/:documentId/uppercase
exports.makeuppercase = onDocumentCreated("/messages/{documentId}", (event) => {
  // Grab the current value of what was written to Firestore.
  const original = event.data.data().original;

  // Access the parameter `{documentId}` with `event.params`
  logger.log("Uppercasing", event.params.documentId, original);

  const uppercase = original.toUpperCase();

  // You must return a Promise when performing
  // asynchronous tasks inside a function
  // such as writing to Firestore.
  // Setting an 'uppercase' field in Firestore document returns a Promise.
  return event.data.ref.set({uppercase}, {merge: true});
});

Python (vista previa)

@firestore_fn.on_document_created(document="messages/{pushId}")
def makeuppercase(
    event: firestore_fn.Event[firestore_fn.DocumentSnapshot | None],
) -> None:
    """Listens for new documents to be added to /messages. If the document has
    an "original" field, creates an "uppercase" field containg the contents of
    "original" in upper case."""

    # Get the value of "original" if it exists.
    if event.data is None:
        return
    try:
        original = event.data.get("original")
    except KeyError:
        # No "original" field, so do nothing.
        return

    # Set the "uppercase" field.
    print(f"Uppercasing {event.params['pushId']}: {original}")
    upper = original.upper()
    event.data.reference.update({"uppercase": upper})


La función “convertir a mayúsculas” se ejecuta cuando se escribe en Cloud Firestore, lo que define el documento en el que se debe escuchar. Por motivos de rendimiento, se debe ser lo más específico posible.

Las llaves, por ejemplo, {documentId}, encierran “parámetros”, comodines que exponen las coincidencias de datos en la devolución de llamada. Cloud Firestore activa la devolución de llamada cada vez que se agregan mensajes nuevos.

En Node.js, las funciones controladas por eventos, como los eventos de Cloud Firestore, son asíncronas. La función de devolución de llamada debería mostrar null, un objeto o una promesa. Si no se muestra nada, se agota el tiempo de espera de la función, se indica un error y se hace un nuevo intento. Consulta Síncrono, asíncrono y promesas.

Emula la ejecución de las funciones

Firebase Local Emulator Suite te permite crear y probar apps en tu máquina local en lugar de implementarlas en un proyecto de Firebase. Se recomienda enfáticamente hacer pruebas locales durante el desarrollo, en parte debido a que reduce el riesgo de cometer errores de codificación que podrían generar costos en un entorno de producción (por ejemplo, bucles infinitos).

Sigue estos pasos para emular las funciones:

  1. Ejecuta firebase emulators:start y verifica la salida de la URL de la IU de Emulator Suite. El valor predeterminado es localhost:4000, pero puede estar alojado en un puerto diferente de tu máquina. Ingresa esa URL en el navegador para abrir la IU de Emulator Suite.

  2. Verifica la salida del comando firebase emulators:start para encontrar la URL de la función de HTTP. Tendrá un aspecto similar a http://localhost:5001/MY_PROJECT/us-central1/addMessage, pero con las siguientes diferencias:

    1. MY_PROJECT se reemplazará por el ID del proyecto.
    2. El puerto podría ser diferente en tu máquina local.
  3. Agrega la cadena de consulta ?text=uppercaseme al final de la URL de la función. Se verá de la siguiente manera: http://localhost:5001/MY_PROJECT/us-central1/addMessage?text=uppercaseme. De manera opcional, puedes cambiar el mensaje “uppercaseme” por un mensaje personalizado.

  4. Para crear un mensaje nuevo, abre la URL en una pestaña nueva del navegador.

  5. Observa los efectos de las funciones en la IU de Emulator Suite:

    1. En la pestaña Registros, deberías ver registros nuevos que indican que se ejecutaron correctamente las funciones de HTTP:

      i functions: Beginning execution of "addMessage"

      i functions: Beginning execution of "makeUppercase"

    2. En la pestaña Firestore, deberías ver un documento que contiene el mensaje original y su versión en mayúsculas (si originalmente era “uppercaseme”, ahora lo verás como “UPPERCASEME”).

Implementa funciones en un entorno de producción

Una vez que funcionen según lo esperado en el emulador, puedes proceder a implementar, probar y ejecutar tus funciones en el entorno de producción. Ten en cuenta que, para llevar a cabo la implementación en producción, tu proyecto debe tener el plan de precios Blaze. Consulta los precios de Cloud Functions.

Para completar el instructivo, implementa las funciones y, luego, ejecútalas.

  1. Ejecuta este comando para implementar las funciones:

     firebase deploy --only functions
     

    Después de ejecutarlo, Firebase CLI genera la URL de los extremos de la función de HTTP, si los hay. En el terminal, deberías ver una línea como la siguiente:

    Function URL (addMessage): https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage
    

    La URL contiene el ID del proyecto y una región para la función de HTTP. Si bien no debes preocuparte por esto, deberías especificar una ubicación para algunas funciones de HTTP de producción a fin de minimizar la latencia en la red.

    Si encuentras errores de acceso como “No se pudo autorizar el acceso al proyecto”, revisa el uso de alias en tu proyecto.

  2. Toma la URL que genera la CLI, agrega un parámetro de consulta de texto y ábrela en un navegador:

    https://us-central1-MY_PROJECT.cloudfunctions.net/addMessage?text=uppercasemetoo
    

    La función se ejecuta y redirecciona el navegador a Firebase console en la ubicación de la base de datos en la que se almacena la cadena de texto. Este evento de escritura activa la función “convertir a mayúsculas”, que escribe una versión de la cadena en mayúsculas.

Después de implementar y ejecutar funciones, puedes ver los registros en la consola de Google Cloud. Usa Firebase CLI para borrar funciones en desarrollo o producción.

En producción, se recomienda optimizar el rendimiento de las funciones y controlar los costos mediante la configuración de la cantidad mínima y máxima de instancias que se ejecutarán. Consulta Controla el comportamiento del escalamiento para obtener más información sobre estas opciones de entorno de ejecución.

Próximos pasos

En esta documentación, podrás obtener más información para administrar funciones en Cloud Functions y controlar todos los tipos de eventos compatibles con Cloud Functions.

Para obtener más información sobre Cloud Functions, puedes hacer lo siguiente: