firebase-admin lambda退出进程nodejs

时间:2018-01-28 21:18:35

标签: node.js firebase aws-lambda firebase-admin

注意新版本的"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();
})
}

1 个答案:

答案 0 :(得分:2)

更新1评论:

根据以下链接,它是允许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

  

当调用回调时,Lambda函数仅在之后退出   Node.js事件循环为空

显然设置context.callbackWaitsForEmptyEventLoop = false;应该可以解决问题,但在我的情况下它不会出现:

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

callbackWaitsForEmptyEventLoop:

  

默认值为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); //<--------
})
}