Me gustaría crear múltiples Cloud Functions para Firebase y desplegarlas todas al mismo tiempo desde un proyecto. También me gustaría separar cada función en un archivo separado. Actualmente puedo crear múltiples funciones si las pongo en index.js como:
exports.foo = functions.database.ref('/foo').onWrite(event => {
...
});
exports.bar = functions.database.ref('/bar').onWrite(event => {
...
});
Sin embargo, me gustaría poner foo y bar en archivos separados. He intentado esto:
/functions
|--index.js (blank)
|--foo.js
|--bar.js
|--package.json
donde foo.js es
exports.foo = functions.database.ref('/foo').onWrite(event => {
...
});
y bar.js es
exports.bar = functions.database.ref('/bar').onWrite(event => {
...
});
¿Hay alguna manera de lograr esto sin poner todas las funciones en index.js?
Ah, Cloud Functions para Firebase carga módulos de nodo normalmente, así que esto funciona
estructura:
/functions
|--index.js
|--foo.js
|--bar.js
|--package.json
index.js:
const functions = require('firebase-functions');
const fooModule = require('./foo');
const barModule = require('./bar');
exports.foo = functions.database.ref('/foo').onWrite(fooModule.handler);
exports.bar = functions.database.ref('/bar').onWrite(barModule.handler);
foo.js:
exports.handler = (event) => {
...
};
bar.js:
exports.handler = (event) => {
...
};
La respuesta de @jasonsirota ha sido muy útil. Pero puede ser útil ver código más detallado, especialmente en el caso de las funciones activadas por HTTP.
Usando la misma estructura que en la respuesta de @jasonsirota, digamos que desea tener dos funciones HTTP disparadas separadas en dos archivos diferentes:
estructura de directorios:
/functions
|--index.js
|--foo.js
|--bar.js
|--package.json`
index.js:
'use strict';
const fooFunction = require('./foo');
const barFunction = require('./bar');
// Note do below initialization tasks in index.js and
// NOT in child functions:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
const database = admin.database();
// Pass database to child functions so they have access to it
exports.fooFunction = functions.https.onRequest((req, res) => {
fooFunction.handler(req, res, database);
});
exports.barFunction = functions.https.onRequest((req, res) => {
barFunction.handler(req, res, database);
});
foo.js:
exports.handler = function(req, res, database) {
// Use database to declare databaseRefs:
usersRef = database.ref('users');
...
res.send('foo ran successfully');
}
bar.js:
exports.handler = function(req, res, database) {
// Use database to declare databaseRefs:
usersRef = database.ref('users');
...
res.send('bar ran successfully');
}
Actualización: Este documento debería ayudar, mi respuesta es más antigua que este documento.
Aquí es cómo yo personalmente lo hice con typescript:
/functions
|--src
|--index.ts
|--http-functions.ts
|--main.js
|--db.ts
|--package.json
|--tsconfig.json
Permítanme hacer un prefacio dando dos advertencias para que esto funcione:
Para el punto número 2 no estoy seguro de por qué. Secundo debes respetar mi configuración de index, main y db exactamente (al menos para probarlo).
index.ts : se ocupa de la exportación. Me parece más limpio dejar que el index.ts se ocupe de las exportaciones.
// main must be before functions
export * from './main';
export * from "./http-functions";
main.ts: Se ocupa de la inicialización.
import { config } from 'firebase-functions';
import { initializeApp } from 'firebase-admin';
initializeApp(config().firebase);
export * from "firebase-functions";
db.ts: Reexporta la base de datos para que su nombre sea más corto que database()
.
import { database } from "firebase-admin";
export const db = database();
http-functions.ts
// db must be imported like this
import { db } from './db';
// you can now import everything from index.
import { https } from './index';
// or (both work)
// import { https } from 'firebase-functions';
export let newComment = https.onRequest(createComment);
export async function createComment(req: any, res: any){
db.ref('comments').push(req.body.comment);
res.send(req.body.comment);
}