¿Cómo estructuro Cloud Functions for Firebase para implementar múltiples funciones desde múltiples archivos?

164

Me gustaría crear múltiples funciones en la nube para Firebase e implementarlas 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. Intenté 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?

jasonsirota
fuente
1
@JPVentura. Realmente no te entiendo bien. Por favor explique.
HuyLe
¿Se ha actualizado esto para v1.0? Tengo problemas: stackoverflow.com/questions/50089807/…
tccpg288
2
Para su información, este ejemplo oficial de funciones de Firebase contiene varios .jsarchivos importados a través de require: github.com/firebase/functions-samples/tree/master/…
xanderiel
Esto podría ser útil: stackoverflow.com/questions/43486278/…
Ramesh-X

Respuestas:

126

Ah, las funciones de nube para los módulos de nodo de carga de Firebase 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) => {
    ...
};
jasonsirota
fuente
1
¿Puedo, por ejemplo, tener varias funciones en el módulo foo? Si es así, ¿cómo es mejor implementarlo?
Alexander Khitev
1
Supongo que podría, y asignar diferentes manejadores a diferentes funciones exportadas de foo: exports.bar = functions.database.ref ('/ foo'). OnWrite (fooModule.barHandler); exportaciones.baz = funciones.database.ref ('/ bar'). onWrite (fooModule.bazHandler);
jasonsirota
44
No me gusta esta solución porque mueve información (es decir, las rutas de acceso a la base de datos) de foo.js y bar.js a index.js, que de alguna manera derrota el punto de tener esos archivos separados.
bvs
Estoy de acuerdo con @bvs, creo que Ced tiene un buen enfoque. Voy a modificarlo ligeramente exportando explícitamente cada módulo para que el index.ts sea súper claro, por ejemplo, exportar {newUser} desde "./authenticationFunctions"
Alan
2
Creo que mi pregunta original era simplemente sobre la implementación de múltiples funciones con 1 proyecto sin poner las funciones en el archivo index.js, dónde y cómo se pasa la información de la base de datos no está dentro del alcance. Si fuera yo, probablemente crearía un módulo separado que controlara el acceso a la base de datos y lo requeriría en foo.js y bar.js por separado, pero esa es una decisión estilística.
jasonsirota
75

La respuesta de @jasonsirota fue muy útil. Pero puede ser útil ver un 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 de disparo HTTP 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'); 
}
Estudiante universitario
fuente
La estructura actual en index.js no funcionó bien para mí. Lo que tenía que hacer era importar primero los módulos de Firebase, luego inicializar la aplicación y luego importar las funciones de las otras carpetas. De esa manera, mi aplicación primero se inicializa, se autentica, lo que sea y luego importa las funciones que necesitan que la aplicación se inicialice de antemano.
tonkatata
47

Actualización: este documento debería ayudar , mi respuesta es anterior a este documento.


Así es como lo hice personalmente con mecanografiado:

/functions
   |--src
      |--index.ts
      |--http-functions.ts
      |--main.js
      |--db.ts
   |--package.json
   |--tsconfig.json

Permítanme presentar esto dando dos advertencias para que esto funcione:

  1. el orden de importación / exportación es importante en index.ts
  2. el db debe ser un archivo separado

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 : trata con la exportación. Me parece más limpio dejar que 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 : simplemente reexportando el db para que su nombre sea más corto quedatabase()

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);
}
Sección de la economía
fuente
¿Cómo es tu tsconfig? ¿Cómo puedo compilar en una carpeta dist y dejar que las funciones de gcloud sepan dónde está mi index.js? ¿Tienes tu código en github? :)
bersling
@ choopage-JekBao lo siento, ha pasado mucho tiempo, ya no tengo el proyecto. Si no recuerdo mal, puede darle a la configuración de Firebase un directorio (que es público de forma predeterminada). Sin embargo, podría estar equivocado, ya que ha pasado más de un año
Ced
Hola @ced: ¿por qué no pueden db.tsentrar los contenidos de main.ts(después de la instancia de administrador?). ¿O simplemente te has separado de esta manera por claridad / simplicidad?
dsg38
1
@ dsg38 esto fue publicado hace mucho tiempo, realmente no veo por qué debería estar en un archivo separado mirando la respuesta ahora ... Creo que fue por claridad
Ced
21

Con el Nodo 8 LTS ahora disponible con Cloud / Firebase Functions, puede hacer lo siguiente con los operadores de propagación:

/package.json

"engines": {
  "node": "8"
},

/index.js

const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();

module.exports = {
  ...require("./lib/foo.js"),
  // ...require("./lib/bar.js") // add as many as you like
};

/lib/foo.js

const functions = require("firebase-functions");
const admin = require("firebase-admin");

exports.fooHandler = functions.database
  .ref("/food/{id}")
  .onCreate((snap, context) => {
    let id = context.params["id"];

    return admin
      .database()
      .ref(`/bar/${id}`)
      .set(true);
  });
Luke Pighetti
fuente
Me pregunto si el creciente número de importaciones se ralentiza al iniciar en frío cada función o si debería haber muchos módulos totalmente separados desarrollados por separado.
Simon Fakir
2
me sale un error de separación de eslint unexpected token ...dentro de index.js.
thomas
Quizás no esté usando el Nodo 8
Luke Pighetti
@SimonFakir buena pregunta. ¿Has encontrado algo al respecto?
atereshkov
@atereshkov sí, encontré una manera de cargar solo la función solicitada, incluidas sus dependencias, usando "process.env.FUNCTION_NAME" similar a la respuesta a continuación. También puedo compartir mi repositorio como referencia si está interesado en ponerse en contacto conmigo.
Simon Fakir
15

Para ser simple (pero hace el trabajo), personalmente he estructurado mi código de esta manera.

Diseño

├── /src/                      
   ├── index.ts               
   ├── foo.ts           
   ├── bar.ts
|   ├── db.ts           
└── package.json  

foo.ts

import * as functions from 'firebase-functions';
export const fooFunction = functions.database()......... {
    //do your function.
}

export const someOtherFunction = functions.database().......... {
    // do the thing.
}

bar.ts

import * as functions from 'firebase-functions';
export const barFunction = functions.database()......... {
    //do your function.
}

export const anotherFunction = functions.database().......... {
    // do the thing.
}

db.ts

import * as admin from 'firebase-admin';
import * as functions from 'firebase-functions';

export const firestore = admin.firestore();
export const realtimeDb = admin.database();

index.ts

import * as admin from 'firebase-admin';
import * as functions from 'firebase-functions';

admin.initializeApp(functions.config().firebase);
// above codes only needed if you use firebase admin

export * from './foo';
export * from './bar';

Funciona para directorios de cualquier nivel anidado. Simplemente siga el patrón dentro de los directorios también.

crédito a @zaidfazil respuesta

Reza
fuente
1
Esta es una de las respuestas más simples para Typecript, gracias. ¿Cómo hacer frente a una sola instanciación de la base de datos de Firebase, por ejemplo? admin.initializeApp(functions.config().firestore) const db = admin.firestore();¿Dónde pones esto y cómo te refieres a él en foo and bar?
elprl
Hola, ¿por qué no pueden db.tsentrar los contenidos de index.ts(después de la instanciación de administrador?). ¿O simplemente te has separado de esta manera por claridad / simplicidad?
dsg38
@ dsg38 puedes mezclar todos juntos, esto lo deja claro
Reza
10

En el caso de Babel / Flow se vería así:

Diseño de directorio

.
├── /build/                     # Compiled output for Node.js 6.x
├── /src/                       # Application source files
   ├── db.js                   # Cloud SQL client for Postgres
   ├── index.js                # Main export(s)
   ├── someFuncA.js            # Function A
   ├── someFuncA.test.js       # Function A unit tests
   ├── someFuncB.js            # Function B
   ├── someFuncB.test.js       # Function B unit tests
   └── store.js                # Firebase Firestore client
├── .babelrc                    # Babel configuration
├── firebase.json               # Firebase configuration
└── package.json                # List of project dependencies and NPM scripts


src/index.js - Exportaciones principales)

export * from './someFuncA.js';
export * from './someFuncB.js';


src/db.js - Cloud SQL Client para Postgres

import { Pool } from 'pg';
import { config } from 'firebase-functions';

export default new Pool({
  max: 1,
  user: '<username>',
  database: '<database>',
  password: config().db.password,
  host: `/cloudsql/${process.env.GCP_PROJECT}:<region>:<instance>`,
});


src/store.js - Cliente de Firebase Firestore

import firebase from 'firebase-admin';
import { config } from 'firebase-functions';

firebase.initializeApp(config().firebase);

export default firebase.firestore();


src/someFuncA.js - Función A

import { https } from 'firebase-functions';
import db from './db';

export const someFuncA = https.onRequest(async (req, res) => {
  const { rows: regions } = await db.query(`
    SELECT * FROM regions WHERE country_code = $1
  `, ['US']);
  res.send(regions);
});


src/someFuncB.js - Función B

import { https } from 'firebase-functions';
import store from './store';

export const someFuncB = https.onRequest(async (req, res) => {
  const { docs: regions } = await store
    .collection('regions')
    .where('countryCode', '==', 'US')
    .get();
  res.send(regions);
});


.babelrc

{
  "presets": [["env", { "targets": { "node": "6.11" } }]],
}


firebase.json

{
  "functions": {
    "source": ".",
    "ignore": [
      "**/node_modules/**"
    ]
  }
}


package.json

{
  "name": "functions",
  "verson": "0.0.0",
  "private": true,
  "main": "build/index.js",
  "dependencies": {
    "firebase-admin": "^5.9.0",
    "firebase-functions": "^0.8.1",
    "pg": "^7.4.1"
  },
  "devDependencies": {
    "babel-cli": "^6.26.0",
    "babel-core": "^6.26.0",
    "babel-jest": "^22.2.2",
    "babel-preset-env": "^1.6.1",
    "jest": "^22.2.2"
  },
  "scripts": {
    "test": "jest --env=node",
    "predeploy": "rm -rf ./build && babel --out-dir ./build src",
    "deploy": "firebase deploy --only functions"
  }
}


$ yarn install                  # Install project dependencies
$ yarn test                     # Run unit tests
$ yarn deploy                   # Deploy to Firebase
Konstantin Tarkus
fuente
9

El esquema bigcodenerd.org es un patrón de arquitectura más simple para separar los métodos en diferentes archivos y exportarlos en una línea dentro del archivo index.js .

La arquitectura para el proyecto en este ejemplo es la siguiente:

projectDirectory

  • index.js
  • podcast.js
  • profile.js

index.js

const admin = require('firebase-admin');
const podcast = require('./podcast');
const profile = require('./profile');
admin.initializeApp();

exports.getPodcast = podcast.getPodcast();
exports.removeProfile = profile.removeProfile();

podcast.js

const functions = require('firebase-functions');

exports.getPodcast = () => functions.https.onCall(async (data, context) => {
      ...
      return { ... }
  });

Se usaría el mismo patrón para el removeProfilemétodo en el archivo de perfil .

Adam Hurwitz
fuente
7

Para ser simple (pero hace el trabajo), personalmente he estructurado mi código de esta manera.

Diseño

├── /src/                      
   ├── index.ts               
   ├── foo.ts           
   ├── bar.ts           
└── package.json  

foo.ts

export const fooFunction = functions.database()......... {
    //do your function.
}

export const someOtherFunction = functions.database().......... {
    // do the thing.
}

bar.ts

export const barFunction = functions.database()......... {
    //do your function.
}

export const anotherFunction = functions.database().......... {
    // do the thing.
}

index.ts

import * as fooFunctions from './foo';
import * as barFunctions from './bar';

module.exports = {
    ...fooFunctions,
    ...barFunctions,
};

Funciona para directorios de cualquier nivel anidado. Simplemente siga el patrón dentro de los directorios también.

zaidfazil
fuente
No puedo ver cómo esto podría funcionar ya que Firebase admite el Nodo 6.11 actualmente, que no admite las directivas de importación ES6.
Aodh
Si está utilizando el mecanografiado, el problema nunca debería surgir. Porté la mayor parte de mi código en mecanografiado últimamente.
zaidfazil
2
zaidfazil, probablemente debería anotar cualquier requisito previo en su respuesta. @Aodh, funciona si usas Babel de la misma manera que Konstantin ha descrito en una respuesta. stackoverflow.com/questions/43486278/…
PostureOfLearning
1
gracias. esto funcionó con el mecanografiado y el nodo 6 :)
Ahmad Moussa
44
En lugar de importar y reexportar con operadores de propagación, ¿no podría simplemente tener export * from './fooFunctions';y export * from './barFunctions';en index.ts?
whatsthatitspat
5

Este formato permite que su punto de entrada encuentre archivos de funciones adicionales y exporte cada función dentro de cada archivo, automáticamente.

Script de punto de entrada principal

Encuentra todos los archivos .js dentro de la carpeta de funciones y exporta cada función exportada desde cada archivo.

const fs = require('fs');
const path = require('path');

// Folder where all your individual Cloud Functions files are located.
const FUNCTIONS_FOLDER = './scFunctions';

fs.readdirSync(path.resolve(__dirname, FUNCTIONS_FOLDER)).forEach(file => { // list files in the folder.
  if(file.endsWith('.js')) {
    const fileBaseName = file.slice(0, -3); // Remove the '.js' extension
    const thisFunction = require(`${FUNCTIONS_FOLDER}/${fileBaseName}`);
    for(var i in thisFunction) {
        exports[i] = thisFunction[i];
    }
  }
});

Ejemplo de exportación de múltiples funciones desde un archivo

const functions = require('firebase-functions');

const query = functions.https.onRequest((req, res) => {
    let query = req.query.q;

    res.send({
        "You Searched For": query
    });
});

const searchTest = functions.https.onRequest((req, res) => {
    res.send({
        "searchTest": "Hi There!"
    });
});

module.exports = {
    query,
    searchTest
}

los puntos finales accesibles http se denominan adecuadamente

✔ functions: query: http://localhost:5001/PROJECT-NAME/us-central1/query
✔ functions: helloWorlds: http://localhost:5001/PROJECT-NAME/us-central1/helloWorlds
✔ functions: searchTest: http://localhost:5001/PROJECT-NAME/us-central1/searchTest

Un archivo

Si solo tiene unos pocos archivos adicionales (por ejemplo, solo uno), puede usar:

const your_functions = require('./path_to_your_functions');

for (var i in your_functions) {
  exports[i] = your_functions[i];
}

Matthew Rideout
fuente
¿No tendrá esto una sobrecarga en el arranque para cada instancia de función que gira?
Ayyappa
4

Así que tengo este proyecto que tiene funciones de fondo y funciones http. También tengo pruebas para pruebas unitarias. CI / CD te facilitará la vida al implementar funciones en la nube

Estructura de carpetas

|-- package.json
|-- cloudbuild.yaml
|-- functions
    |-- index.js
    |-- background
    |   |-- onCreate
    |       |-- index.js
            |-- create.js
    |
    |-- http
    |   |-- stripe
    |       |-- index.js
    |       |-- payment.js
    |-- utils
        |-- firebaseHelpers.js
    |-- test
        |-- ...
    |-- package.json

Nota: la utils/ carpeta es para compartir código entre funciones

funciones / index.js

Aquí puede importar todas las funciones que necesita y declararlas. No es necesario tener lógica aquí. Lo hace más limpio en mi opinión.

require('module-alias/register');
const functions = require('firebase-functions');

const onCreate = require('@background/onCreate');
const onDelete = require('@background/onDelete');
const onUpdate = require('@background/onUpdate');

const tours  = require('@http/tours');
const stripe = require('@http/stripe');

const docPath = 'tours/{tourId}';

module.exports.onCreate = functions.firestore.document(docPath).onCreate(onCreate);
module.exports.onDelete = functions.firestore.document(docPath).onDelete(onDelete);
module.exports.onUpdate = functions.firestore.document(docPath).onUpdate(onUpdate);

module.exports.tours  = functions.https.onRequest(tours);
module.exports.stripe = functions.https.onRequest(stripe);

CI / CD

¿Qué le parece tener una integración y una implementación continuas cada vez que envía sus cambios al repositorio? Puedes tenerlo usando google google cloud build . Es gratis hasta cierto punto :) Mira este enlace .

./cloudbuild.yaml

steps:
  - name: "gcr.io/cloud-builders/npm"
    args: ["run", "install:functions"]
  - name: "gcr.io/cloud-builders/npm"
    args: ["test"]
  - name: "gcr.io/${PROJECT_ID}/firebase"
    args:
      [
        "deploy",
        "--only",
        "functions",
        "-P",
        "${PROJECT_ID}",
        "--token",
        "${_FIREBASE_TOKEN}"
      ]

substitutions:
    _FIREBASE_TOKEN: nothing
ajorquera
fuente
He exportado como dijiste, pero el despliegue de Firebase detecta el que está al final, por ejemplo: según tu código, solo toma module.exports.stripe = functions.https.onRequest (stripe);
OK200
@ OK200 ¿Cuál es el comando que está utilizando con la línea de comandos de Firebase? Para ayudarlo, necesitaré ver un código
ajorquera,
3

Hay una forma bastante buena de organizar todas sus funciones en la nube a largo plazo. Hice esto recientemente y está funcionando perfectamente.

Lo que hice fue organizar cada función de la nube en carpetas separadas según su punto final de activación. Cada nombre de archivo de función de nube termina con *.f.js. Por ejemplo, si tenía onCreatey onUpdateactivadores user/{userId}/document/{documentId}, cree dos archivos onCreate.f.jsy onUpdate.f.jsen el directorio functions/user/document/y su función se nombrará userDocumentOnCreatey userDocumentOnUpdaterespectivamente. (1)

Aquí hay una estructura de directorio de muestra:

functions/
|----package.json
|----index.js
/----user/
|-------onCreate.f.js
|-------onWrite.f.js
/-------document/
|------------onCreate.f.js
|------------onUpdate.f.js
/----books/
|-------onCreate.f.js
|-------onUpdate.f.js
|-------onDelete.f.js

Función de muestra

const functions = require('firebase-functions');
const admin = require('firebase-admin');
const db = admin.database();
const documentsOnCreate = functions.database
    .ref('user/{userId}/document/{documentId}')
    .onCreate((snap, context) => {
        // your code goes here
    });
exports = module.exports = documentsOnCreate;

Index.js

const glob = require("glob");
const camelCase = require('camelcase');
const admin = require('firebase-admin');
const serviceAccount = require('./path/to/ServiceAccountKey.json');
try {
    admin.initializeApp({ credential: admin.credential.cert(serviceAccount),
    databaseURL: "Your database URL" });
} catch (e) {
    console.log(e);
}

const files = glob.sync('./**/*.f.js', { cwd: __dirname });
for (let f = 0, fl = files.length; f < fl; f++) {
    const file = files[f];
    const functionName = camelCase(file.slice(0, -5).split('/')); 
    if (!process.env.FUNCTION_NAME || process.env.FUNCTION_NAME === functionName) {
        exports[functionName] = require(file);
      }
}

(1): puede usar el nombre que desee. Para mí, onCreate.f.js, onUpdate.f.js, etc. parecen más relevantes para el tipo de disparador que son.

krhitesh
fuente
1
Este enfoque es realmente agradable. Me preguntaba si es posible ajustar para permitir barras en los nombres de las funciones para que pueda separar diferentes versiones de la API, por ejemplo (api v1, api v2, etc.)
Alex Sorokoletov
¿Por qué querría mantener diferentes versiones de una función en la nube en el mismo proyecto? Aunque puede hacerlo cambiando ligeramente la estructura del directorio, por defecto index.js implementará todas las funciones de la nube a menos que implemente selectivamente o use condiciones if en su index.js que eventualmente terminará
abarrotando
1
Estoy de acuerdo con implementar todo, solo quiero versionar las funciones que puse (activadas por http)
Alex Sorokoletov
Espero que cada disparador http esté en su propio *.f.jsarchivo. Lo menos que puede hacer es cambiar el nombre del archivo para todas las versiones anteponiendo el sufijo para que sea algo parecido *.v1.f.jso *.v2.f.jsetc (Suponiendo que todas sus versiones de la totalidad de su gatillo http son en vivo). Avíseme si tiene una mejor solución.
krhitesh
1

Utilizo un cargador de arranque JS de vainilla para incluir automáticamente todas las funciones que quiero usar.

├── /functions
   ├── /test/
      ├── testA.js
      └── testB.js
   ├── index.js
   └── package.json

index.js (gestor de arranque)

/**
 * The bootloader reads all directories (single level, NOT recursively)
 * to include all known functions.
 */
const functions = require('firebase-functions');
const fs = require('fs')
const path = require('path')

fs.readdirSync(process.cwd()).forEach(location => {
  if (!location.startsWith('.')) {
    location = path.resolve(location)

    if (fs.statSync(location).isDirectory() && path.dirname(location).toLowerCase() !== 'node_modules') {
      fs.readdirSync(location).forEach(filepath => {
        filepath = path.join(location, filepath)

        if (fs.statSync(filepath).isFile() && path.extname(filepath).toLowerCase() === '.js') {
          Object.assign(exports, require(filepath))
        }
      })
    }
  }
})

Este archivo index.js de ejemplo solo incluye automáticamente directorios dentro de la raíz. Se podría ampliar para recorrer directorios, honrar .gitignore, etc. Sin embargo, esto fue suficiente para mí.

Con el archivo de índice en su lugar, agregar nuevas funciones es trivial.

/test/testA.js

const functions = require('firebase-functions');

exports.helloWorld = functions.https.onRequest((request, response) => {
 response.send("Hello from Firebase!");
});

/test/testB.js

const functions = require('firebase-functions');

exports.helloWorld2 = functions.https.onRequest((request, response) => {
 response.send("Hello again, from Firebase!");
});

npm run serve rendimientos:

λ ~/Workspace/Ventures/Author.io/Firebase/functions/ npm run serve

> functions@ serve /Users/cbutler/Workspace/Ventures/Author.io/Firebase/functions
> firebase serve --only functions


=== Serving from '/Users/cbutler/Workspace/Ventures/Author.io/Firebase'...

i  functions: Preparing to emulate functions.
Warning: You're using Node.js v9.3.0 but Google Cloud Functions only supports v6.11.5.
✔  functions: helloWorld: http://localhost:5000/authorio-ecorventures/us-central1/helloWorld
✔  functions: helloWorld2: http://localhost:5000/authorio-ecorventures/us-central1/helloWorld2

Este flujo de trabajo es simplemente "escribir y ejecutar", sin tener que modificar el archivo index.js cada vez que se agrega / modifica / elimina una nueva función / archivo.

Corey
fuente
¿No será esto en arranque en frío?
Ayyappa
1

Aquí hay una respuesta simple si está creando funciones en la nube con mecanografiado.

/functions
|--index.ts
|--foo.ts

Cerca de todas sus importaciones regulares en la parte superior, simplemente exporte todas las funciones foo.ts.

export * from './foo';

Markymark
fuente