我想为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中的情况下实现这一点?
我也在为云函数寻找最佳的文件夹结构,所以我决定分享我的想法:
+ /src
| - index.ts
| + /events
| | - moduleA_events.ts
| | - moduleB_events.ts
| + /service
| | - moduleA_services.ts
| | - moduleB_services.ts
| + /model
| | - objectA.ts
| | - objectB.ts
| | - objectC.ts
/ src /索引。Ts此文件作为应用程序中所有可用事件(函数)的入口点,如数据库事件,HTTPS请求,计划函数。然而,函数不是直接在index.js中声明的,而是在事件文件夹indead中声明的。代码示例:
出口。user = require("./events/userEvents")
出口。order = require("./events/orderEvents")
出口。product = require("./events/productEvents")
注意:根据GCF官方文档,这种方法会自动将所有函数重命名为“模块-函数”模式。示例:如果在userEvents中有"userCreated"函数。ts, firebase将重命名此函数为"user-userCreated"
/src/events this folder should only contain cloud functions declarations and should not handle business logic directly. For the actual business, you should call custom functions from your /service folder (which maps the same modules as in the events folder). Code sample for userEvents.ts:
exports.userCreated = functions.firestore.document("/users/{documentId}").onCreate(async (snapshot) => {
userServices.sendWelcomeEmail()
}
/src/service the actual busienss logic that will connect with other firebase services such as firestore, storage, auth. You can also import your /model layer here (typescript only).
/src/model the interfaces used in typescript to ensure strong typed functions and objects.
正如您所注意到的,这种方法主要基于MVC和OOP原则。有很多关于我们是否应该在无服务器环境中使用函数式编程的争论。由于我的后台背景是Java和c#,我在这里介绍的文件夹结构对我来说似乎更自然,然而,我很想知道当转向函数式编程方法时,这种文件夹结构会有什么不同。
这种格式允许您的入口点查找其他函数文件,并自动导出每个文件中的每个函数。
主要入口脚本
找到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的答案
我也在为云函数寻找最佳的文件夹结构,所以我决定分享我的想法:
+ /src
| - index.ts
| + /events
| | - moduleA_events.ts
| | - moduleB_events.ts
| + /service
| | - moduleA_services.ts
| | - moduleB_services.ts
| + /model
| | - objectA.ts
| | - objectB.ts
| | - objectC.ts
/ src /索引。Ts此文件作为应用程序中所有可用事件(函数)的入口点,如数据库事件,HTTPS请求,计划函数。然而,函数不是直接在index.js中声明的,而是在事件文件夹indead中声明的。代码示例:
出口。user = require("./events/userEvents")
出口。order = require("./events/orderEvents")
出口。product = require("./events/productEvents")
注意:根据GCF官方文档,这种方法会自动将所有函数重命名为“模块-函数”模式。示例:如果在userEvents中有"userCreated"函数。ts, firebase将重命名此函数为"user-userCreated"
/src/events this folder should only contain cloud functions declarations and should not handle business logic directly. For the actual business, you should call custom functions from your /service folder (which maps the same modules as in the events folder). Code sample for userEvents.ts:
exports.userCreated = functions.firestore.document("/users/{documentId}").onCreate(async (snapshot) => {
userServices.sendWelcomeEmail()
}
/src/service the actual busienss logic that will connect with other firebase services such as firestore, storage, auth. You can also import your /model layer here (typescript only).
/src/model the interfaces used in typescript to ensure strong typed functions and objects.
正如您所注意到的,这种方法主要基于MVC和OOP原则。有很多关于我们是否应该在无服务器环境中使用函数式编程的争论。由于我的后台背景是Java和c#,我在这里介绍的文件夹结构对我来说似乎更自然,然而,我很想知道当转向函数式编程方法时,这种文件夹结构会有什么不同。
在我努力实现@zaidfazil的解决方案时,我想出了以下方法(使用JavaScript,而不是TypeScript)。
multi.js
exports.onQuestionMultiCreate = functions.database
.ref("/questions-multi/{questionId}")
.onCreate(async (snapshot, context) => {
...
}
});
trueFalse.js
exports.onQuestionTrueFalseCreate = functions.database
.ref("/questions-truefalse/{questionId}")
.onCreate(async (snapshot, context) => {
...
}
});
index.js
const multi = require("./multi");
const trueFalse = require("./trueFalse");
module.exports = {
...multi,
...trueFalse
为了保持简单(但能完成工作),我个人是这样构造我的代码的。
布局
├── /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,
};
适用于任何嵌套级别的目录。也只需遵循目录中的模式即可。