注意新版本的"firebase-admin": "^5.0.0"
和aws lambda,即使回调被成功触发,进程也不会退出:
var admin = require("firebase-admin");
var serviceAccount = require("./your-creds.json");
var admin = require("firebase-admin");
var serviceAccount = require("./your-creds.json");
if(admin.apps.length == 0) {
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "your DB.com"
});
}
module.exports.hello = (event, context, callback) => {
admin.database().ref('/').set({
username: "stackoverflow",
email: "test@mail.com"
}).then((data)=>{
callback(null, { statusCode: 200});
context.succeed();
}).catch((err) => {
console.log(err);
callback({ statusCode: 500});
context.fail();
})
}
答案 0 :(得分:2)
根据以下链接,它是允许Node.js执行非阻塞I / O操作的事件循环。 https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/
使用admin.database()
初始化firebase时,似乎初始化此repo:https://github.com/firebase/firebase-js-sdk/blob/72cd164614b3eef29012c6343fd38ce38fef46d6/packages/database/src/core/Repo.ts它必须为事件循环的某些不同阶段设置正在进行的操作,例如: poll
保持持久的websocket连接(猜测)
由于lambda函数在node.js事件循环为空之前永远不会退出,即使调用callback
方法,函数调用也不会退出:
当调用回调时,Lambda函数仅在之后退出 Node.js事件循环为空
显然设置context.callbackWaitsForEmptyEventLoop = false;
应该可以解决问题,但在我的情况下它不会出现:
https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html
默认值为true。此属性仅用于修改回调的默认行为。默认情况下,回调将 等到Node.js运行时事件循环为空,然后才冻结 处理并将结果返回给调用者。你可以设置它 property为false以请求AWS Lambda尽快冻结进程 调用回调后,即使事件中有事件 环。 AWS Lambda将冻结进程,任何状态数据和 Node.js事件循环中的事件(事件中的任何剩余事件) 接下来调用Lambda函数并且如果是AWS,则处理循环 Lambda选择使用冷冻过程)。有关的更多信息 回调,请参阅使用回调参数。
但是,调用admin.app().delete()
会释放所有资源,从而清除事件循环并允许lambda函数退出。
呈现此应用程序无法使用并释放所有关联的资源 服务
https://firebase.google.com/docs/reference/js/firebase.app.App#delete
因此,如果我将我的代码更改为低于它,则在回调后退出:
admin.database().ref('/').set({
username: "stackoverflow",
email: "test@mail.com"
}).then((data)=>{
admin.app().delete().then(callback(null, { statusCode: 200}))
}).catch((err) => {
console.log(err);
})
通过使用进程退出解决了该问题,如下所示。如果有人知道发生这种情况的原因请详细说明:
var admin = require("firebase-admin");
var serviceAccount = require("./your-creds.json");
var admin = require("firebase-admin");
var serviceAccount = require("./your-creds.json");
if(admin.apps.length == 0) {
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "your DB.com"
});
}
module.exports.hello = (event, context, callback) => {
admin.database().ref('/').set({
username: "stackoverflow",
email: "test@mail.com"
}).then((data)=>{
callback(null, { statusCode: 200});
context.succeed();
process.exit(0); //<--------
}).catch((err) => {
console.log(err);
callback({ statusCode: 500});
context.fail()
process.exit(1); //<--------
})
}