我想为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;