我想为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中的情况下实现这一点?
org大纲是一个更简单的体系结构模式,可以将方法分离到不同的文件中,并在index.js文件中的一行中导出。
本示例中项目的架构如下:
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 { ... }
});
同样的模式将用于概要文件中的removeProfile方法。
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负载节点模块的云函数通常,所以这是有效的
结构:
/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) => {
...
};
为了保持简单(但能完成工作),我个人是这样构造我的代码的。
布局
├── /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的答案
在我努力实现@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
Node 8 LTS现在可以与Cloud/Firebase函数一起使用,您可以使用扩展操作符执行以下操作:
/ 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);
});