Según la documentación de Firebase, las Cloud Functions son piezas de código que te permiten correr código del BackEnd en respuesta a un evento dentro de Firebase o a peticiones HTTP.

Al trabajar con ellas podemos usar nuestro Backend basado en funciones para cualquier ambiente, tanto para nuestro sitio web como para una aplicación móvil que tengamos y sin escalar ningún tipo de servidores ni ninguna otra operación relacionada.

Lo que vamos a crear es una especie de API básica basada en Cloud Functions. Esta usará el trigger de HTTP para gestionar las peticiones y los datos que se alojarán en la base de datos de Firebase.

Un trigger es, según su definición un pulso o circuito que inicia la acción de otro componente. Podemos entenderlo como la entrada que necesitamos para trabajar en las funciones. En Firebase contamos con triggers de la base de datos, HTTP, autenticación, almacenamiento…

Paso 1: Preparar el ambiente. Instalación de dependencias y configuración del Firebase Hosting.

Para comenzar a trabajar con el proyecto es necesario que instalemos el CLI de Firebase. Este nos ayudará a crear las carpetas y archivos necesarios para crear las funciones así como para hacer el deploy. Para ello ejecutamos:

$ npm install -g firebase-tools
$ firebase login

Para incializar nuestro proyecto simplemente hacemos:

$ firebase init

Durante este último comando deberás de elegir que es un proyecto de funciones, así como una app que debes crear en la consola de administración de Firebase. Esto creará algunos archivos y carpetas con los que vamos a trabajar más adelante.

Finalmente, es necesario crear una página de Hello World, ya que al publicar nuestras funciones estás tendrán una URL asignada pero no guardará relación ninguna con la de nuestra aplicación. Lo ideal sería que estas se ejecutaran al realizar peticiones sobre /api como cualquier otra aplicación. Para hacer estas redirecciones necesitamos al menos un archivo subido. Creamos el archivo /public/index.html y le añadimos lo siguiente:

<h1>Hello World</h1>

Paso 2: Creando la ruta GET

Para comenzar a trabajar con nuestra API necesitamos conectar la función que vayamos a usar con la base de datos de nuestra aplicación. Para trabajar con Firebase en Node necesitaremos el módulo firebase-admin:

$ npm install --save firebase-admin

El archivo en el que trabajaremos las funciones será /functions/index.js, borramos todo el contenido y importamos los módulos que vamos a necesitar:

const functions = require('firebase-functions');
const firebase = require('firebase-admin') // Trabajar con la base de datos
const config = require('./firebase-config.json')

firebase.initializeApp({
    credential: firebase.credential.cert(config),
    databaseURL: 'https://miprimerappconfunciones.firebaseio.com/'
})

Si te fijas en la línea 3 hemos importado un archivo de configuración para que firebase-admin pueda trabajar correctamente. Revisa la documentación para aprender a descargarlo.

Para crear la función que necesitamos simplemente exportamos una función de Express, usando el trigger de HTTP, tal que así:

exports.apartaments = functions.https.onRequest((req, res) => {
     if(req.method == 'GET') { //Verifica si es GET
         const apartaments = firebase.database().ref('/apartaments') // Referencia a la base de datos
         apartaments.on('value', (snapshot) => {
             res.json(snapshot.val()) //Manda los datos obtenidos en JSON
         })
     }
 })

Una vez lo tengamos, podemos crear cualquier tipo de información encapsulada en apartaments, para que se muestre en nuestra aplicación en formato JSON, tal que así:

¡La primera ruta está lista! Para poder subir nuestro Hello World y las funciones debemos de hacer deploy a Firebase, esto se realiza con el comando:

$ firebase deploy

Si vamos en el panel de Firebase a el apartado de funciones, veremos la función registrada y su respectiva URL:

Como ya habíamos comentado esta URL es un poco engorrosa. Lo ideal sería que al pedidir la URL de nuestra aplicación con /api/apartaments esta cumpliera la función que acabamos de crear. Para conseguir esto editamos el archivo firebase.json de la siguiente manera:

{
    hosting: {
        public: "public",
        rewrites: [
            {
                source: "/api/apartaments",
                function: "apartaments"
            }
        ]
    }
}

Paso 3: Creando la ruta POST

Para finalizar nuestro ejemplo vamos a crear un ejemplo más, esta vez de una ruta de tipo POST con el fin de ver que podemos crear un API completa. Para ello tenemos que usar la misma función que hemos creado.

La solución está en extender nuestro un if, puesto que si te fijas dentro de la función tenemos acceso a el objeto request y este tiene el método de la petición(la documentación está al final del artículo).

Por tanto, nuestra función pasaría a establecerse de la siguiente manera:

exports.apartaments = functions.https.onRequest((req, res) => {
    if(req.method == 'GET') {
        const apartaments = firebase.database().ref('/apartaments')
        apartaments.on('value', (snapshot) => {
            res.json(snapshot.val())
        })
    } else if (req.method == 'POST') {
        const apartaments = firebase.database().ref('/apartaments')
        const apartament = req.body // El objeto que mandemos.
        apartaments.push(apartament) // Crea un nuevo objeto con ID aleatorio.
            .then(res.json(apartament))
            .catch(err => res.json(err))
    }
})

Para poder hacer funcionar nuestra nueva versión de la API hacemos $ firebaase deploy de nuevo y probamos con cualquier herramienta que tengamos a la mano. En mi caso usaré Postman:

Conclusiones

Las Cloud Functions pueden resolver casi cualquier necesidad que tengamos para nuestra aplicación, aplicando la lógica y la experiencia que tengamos en NodeJS podemos llegar a construir cosas muy robustas con solo unas líneas de código.

En el ámbito de mejora de la aplicación, se podría crear otra función que desplegara un solo apartamento y poder editar y eliminar este. Todas las ideas que se te ocurran para el proyecto son bienvenidas mediante un Pull Request al repositorio. El enlace está en la sección de documentación.

Si te quedó alguna duda o curiosidad o simplemente ganas de saber más al final del artículo están habilitados los comentarios para poder iniciar un debate. También como ya te he mencionado te dejo documentación de sobra para que aprendas más sobre Firebase y las Cloud Functions.

Documentación