firebase-admin lambda 退出进程 nodejs

firebase-admin lambda exit process nodejs

使用 aws lambda 的新版本 "firebase-admin": "^5.0.0" 注意,即使成功触发回调,进程也不会退出:

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: "Whosebug",
   email: "test@mail.com"
 }).then((data)=>{
   callback(null, { statusCode: 200});
   context.succeed();
}).catch((err) => {
   console.log(err);
   callback({ statusCode: 500});
   context.fail();
})
}

更新 1 条评论:

根据下面的link,事件循环允许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 方法,函数调用也不会退出:

https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html#nodejs-prog-model-handler-callback

When the callback is called, the Lambda function exits only after the Node.js event loop is empty

显然设置 context.callbackWaitsForEmptyEventLoop = false; 应该可以解决问题,但在我的情况下却没有:

https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html

callbackWaitsForEmptyEventLoop :

The default value is true. This property is useful only to modify the default behavior of the callback. By default, the callback will wait until the Node.js runtime event loop is empty before freezing the process and returning the results to the caller. You can set this property to false to request AWS Lambda to freeze the process soon after the callback is called, even if there are events in the event loop. AWS Lambda will freeze the process, any state data and the events in the Node.js event loop (any remaining events in the event loop processed when the Lambda function is called next and if AWS Lambda chooses to use the frozen process). For more information about callback, see Using the Callback Parameter.

但是调用 admin.app().delete() 会释放所有资源,从而清除事件循环并允许 lambda 函数退出。

删除:

Renders this app unusable and frees the resources of all associated services

https://firebase.google.com/docs/reference/js/firebase.app.App#delete

因此,如果我将我的代码更改为以下代码,它会在回调后退出:

admin.database().ref('/').set({
    username: "Whosebug",
    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: "Whosebug",
   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); //<--------
})
}