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.

Para este ejemplo elegimos Cloud Firestore y funciones de JavaScript 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, Pub/Sub, Auth y HTTP. Otros tipos de activadores en segundo plano, como Remote Config, Test Lab y Analytics, 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 crear, probar e implementar la muestra. Si solo quieres ejecutar e inspeccionar el código, ve a Revisa el código completo de 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 Node.js y Firebase CLI

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.

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, y debes elegir TypeScript o JavaScript para escribir 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 dos opciones de lenguaje:

    En este instructivo, selecciona JavaScript.

  6. CLI te ofrece una opción para instalar las dependencias con npm. Es seguro rechazarla si quieres administrar las dependencias de otra manera, pero, si lo haces, deberás ejecutar npm install antes de emular o implementar tus funciones.

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

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

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

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 con declaraciones require de Node. Agrega líneas como las siguientes al archivo index.js:

// The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
const functions = require('firebase-functions/v1');

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

Estas líneas cargan los módulos firebase-functions y firebase-admin. 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 módulos de Node.js y del SDK de Firebase para Cloud Functions cuando inicializas tu proyecto. Para agregar bibliotecas de terceros al proyecto, puedes modificar el archivo package.json y ejecutar npm install. Para obtener más información, consulta Cómo controlar dependencias.

Agrega la función addMessage()

Para la función addMessage(), agrega estas líneas a index.js:

// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addMessage = functions.https.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 admin
    .firestore()
    .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.` });
});

La función addMessage() es un extremo de HTTP. Cada solicitud que se envía al extremo hace que los objetos Request y Response de estilo ExpressJS se pasen a la devolución de llamada onRequest().

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 addMessage() 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 makeUppercase()

Para la función makeUppercase(), agrega estas líneas a index.js:

// Listens for new messages added to /messages/:documentId/original and creates an
// uppercase version of the message to /messages/:documentId/uppercase
exports.makeUppercase = functions.firestore
  .document("/messages/{documentId}")
  .onCreate((snap, context) => {
    // Grab the current value of what was written to Firestore.
    const original = snap.data().original;

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

    const uppercase = original.toUpperCase();

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

La función makeUppercase() se ejecuta cuando se escribe en Cloud Firestore. La función ref.set define el documento 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 onCreate() cada vez que se agregan mensajes nuevos.

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 addMessage(). 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 las funciones addMessage() y makeUppercase():

      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 esta implementación en el entorno de ejecución recomendado de Node.js 14, tu proyecto debe tener el plan de precios Blaze. Consulta los precios de Cloud Functions.

Para completar el instructivo, implementa las funciones y, luego, ejecuta addMessage() para activar makeUppercase().

  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 de addMessage() 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 makeUppercase(), que escribe una versión de la string 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.

Revisa el código completo de la muestra

Aquí se muestra la versión completa de functions/index.js que contiene las funciones addMessage() y makeUppercase(). Estas funciones te permiten pasarle un parámetro a un extremo HTTP que escribe un valor en Cloud Firestore y, luego, lo transforma mediante la conversión a mayúsculas de todos los caracteres de la string.

// The Cloud Functions for Firebase SDK to create Cloud Functions and set up triggers.
const functions = require('firebase-functions/v1');

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

// Take the text parameter passed to this HTTP endpoint and insert it into
// Firestore under the path /messages/:documentId/original
exports.addMessage = functions.https.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 admin
    .firestore()
    .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 creates an
// uppercase version of the message to /messages/:documentId/uppercase
exports.makeUppercase = functions.firestore
  .document("/messages/{documentId}")
  .onCreate((snap, context) => {
    // Grab the current value of what was written to Firestore.
    const original = snap.data().original;

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

    const uppercase = original.toUpperCase();

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

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: