我想为Firebase创建多个云功能,并从一个项目同时部署它们。我还想将每个函数分离到一个单独的文件中。目前,我可以创建多个函数,如果我把它们都放在index.js,如:

exports.foo = functions.database.ref('/foo').onWrite(event => {
    ...
});

exports.bar = functions.database.ref('/bar').onWrite(event => {
    ...
});

然而,我想把foo和酒吧在单独的文件。我试了一下:

/functions
|--index.js (blank)
|--foo.js
|--bar.js
|--package.json

foo.js在哪里

exports.foo = functions.database.ref('/foo').onWrite(event => {
    ...
});

bar.js是

exports.bar = functions.database.ref('/bar').onWrite(event => {
    ...
});

有没有一种方法可以在不把所有函数都放在index.js中的情况下实现这一点?


当前回答

这种格式允许您的入口点查找其他函数文件,并自动导出每个文件中的每个函数。

主要入口脚本

找到functions文件夹中的所有.js文件,并导出从每个文件中导出的每个函数。

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]; } } });

从一个文件导出多个函数

Const functions = require('firebase-functions'); Const query = functions.https。onRequest((req, res) => { Let query = req.query.q; res.send ({ “You searching For”:查询 }); }); const searchTest = functions.https。onRequest((req, res) => { res.send ({ "searchTest": "你好!" }); }); 模块。出口= { 查询 searchTest }

HTTP可访问端点有适当的命名

✔功能:查询:http://localhost:5001/PROJECT-NAME/us-central1/query function: helloWorlds: http://localhost:5001/PROJECT-NAME/us-central1/helloWorlds ✔功能:searchTest: http://localhost:5001/PROJECT-NAME/us-central1/searchTest

一个文件

如果你只有几个额外的文件(例如只有一个),你可以使用:

Const your_functions = require('./path_to_your_functions'); For (var I in your_functions) { export [i] = your_functions[i]; }

其他回答

为了保持简单(但能完成工作),我个人是这样构造我的代码的。

布局

├── /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';

适用于任何嵌套级别的目录。也只需遵循目录中的模式即可。

这要归功于@zaidfazil的答案

这种格式允许您的入口点查找其他函数文件,并自动导出每个文件中的每个函数。

主要入口脚本

找到functions文件夹中的所有.js文件,并导出从每个文件中导出的每个函数。

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]; } } });

从一个文件导出多个函数

Const functions = require('firebase-functions'); Const query = functions.https。onRequest((req, res) => { Let query = req.query.q; res.send ({ “You searching For”:查询 }); }); const searchTest = functions.https。onRequest((req, res) => { res.send ({ "searchTest": "你好!" }); }); 模块。出口= { 查询 searchTest }

HTTP可访问端点有适当的命名

✔功能:查询:http://localhost:5001/PROJECT-NAME/us-central1/query function: helloWorlds: http://localhost:5001/PROJECT-NAME/us-central1/helloWorlds ✔功能:searchTest: http://localhost:5001/PROJECT-NAME/us-central1/searchTest

一个文件

如果你只有几个额外的文件(例如只有一个),你可以使用:

Const your_functions = require('./path_to_your_functions'); For (var I in your_functions) { export [i] = your_functions[i]; }

我有这个项目,它有后台函数和http函数。我还有用于单元测试的测试。CI/CD将使您在部署云功能时更加轻松

文件夹结构

|-- 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

注意:utils/文件夹用于在函数之间共享代码

函数/ index.js

在这里,您可以导入所需的所有函数并声明它们。这里不需要逻辑。在我看来,这样更干净。

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

每次将更改推送到回购时都进行持续集成和部署如何?你可以使用谷歌谷歌云构建。它是免费的,直到某个点:)检查这个链接。

。/ 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

Firebase文档现在已经更新了一个多文件代码组织的好指南:

文档>云功能>写功能>组织功能

总结:

foo.js

const functions = require('firebase-functions');
exports.foo = functions.https.onRequest((request, response) => {
  // ...
});

bar.js

const functions = require('firebase-functions');
exports.bar = functions.https.onRequest((request, response) => {
  // ...
});

index.js

const foo = require('./foo');
const bar = require('./bar');
exports.foo = foo.foo;
exports.bar = bar.bar;

我花了很多时间寻找同样的东西,我认为这是实现它的最佳方法(我使用firebase@7.3.0):

https://codeburst.io/organizing-your-firebase-cloud-functions-67dc17b3b0da

毫不费力;)