[英]Node.js 12.x AWS lambda does not return using firebase-admin realtime database
I've been stuck on this issue for days with little to no progress, please help if you can!我已经在这个问题上卡了几天了,几乎没有进展,如果可以的话,请帮忙!
I have a Node.js (v12) AWS Lambda that needs to pull data from my Firebase realtime database and process each record into a Redis cache if it doesn't exist already. I have a Node.js (v12) AWS Lambda that needs to pull data from my Firebase realtime database and process each record into a Redis cache if it doesn't exist already. The function starts but never finishes and instead I receive
Task timed out after 180.10 seconds
from AWS. function 启动但从未完成,相反我收到来自 AWS
Task timed out after 180.10 seconds
。
Things I've tried:我尝试过的事情:
exports.handler = async function(event)
versus exports.handler = function(event, context, callback)
;exports.handler = async function(event)
与exports.handler = function(event, context, callback)
;context.callbackWaitsForEmptyEventLoop = false
versus not;context.callbackWaitsForEmptyEventLoop = false
而不是;.then()
's together;.then()
拼接在一起;firebase-admin
versus the https
module in-conjunction with the Firebase REST API;firebase-admin
与https
模块与 Firebase REST ZDB97477ACE41 结合使用settimeout
to fire the callback later versus not;settimeout
稍后触发回调而不是不使用;GOOGLE_APPLICATION_CREDENTIALS
environment variable to my service account credentials versus referencing the file directly in the code;GOOGLE_APPLICATION_CREDENTIALS
环境变量设置为我的服务帐户凭据,而不是直接在代码中引用文件; Responses I've had as-per the attempts above:根据上述尝试,我得到的回应:
Task timed out after 180.10 seconds
; Task timed out after 180.10 seconds
;.then
stitching approach): Function completed successfully
(but no data was actually processed); .then
拼接方式): Function completed successfully
(但实际没有处理数据);ETIMEDOUT
or ECONNREFUSED
;ETIMEDOUT
或ECONNREFUSED
; Below is where I'm up to and still no luck.下面是我的目标,但仍然没有运气。 I have cut-out the caching code since I know that works fine.
我已经删除了缓存代码,因为我知道它可以正常工作。 The
settimeout
's you see were my last resorts before reaching out here.你看到的
settimeout
是我到达这里之前的最后手段。
const admin = require("firebase-admin");
admin.initializeApp({
credential: admin.credential.applicationDefault(),
databaseURL: "https://{projectName}.firebaseio.com"
});
var result = [];
exports.handler = (event, context, callback) => {
context.callbackWaitsForEmptyEventLoop = false;
try {
admin.database().ref("data").orderByChild("timestamp").limitToLast(1).once("value", snapshot => {
if (snapshot.exists()) {
console.log('snapshot exists...');
let posts = snapshot.val();
result = Object.keys(posts);
}
setTimeout(() => {
admin.database().goOffline();
admin.app().delete();
callback(null, `Success! ${JSON.stringify(result)}`); // <-- NEVER RETURNS
}, 2000);
}, error => {
setTimeout(() => {
admin.database().goOffline();
admin.app().delete();
callback(error); // <-- NEVER RETURNS
}, 2000);
});
} catch (error) {
setTimeout(() => {
admin.database().goOffline();
admin.app().delete();
callback(error); // <-- NEVER RETURNS
}, 2000);
}
};
It doesn't appear you are storing or using the setTimeout on the root level of your function.您似乎没有在 function 的根级别上存储或使用 setTimeout。 You should store it so the call back function can keep running since it only exists while it's in scope.
您应该存储它,以便回调 function 可以继续运行,因为它只存在于 scope 中。 Doing this also requires you to bind the object so you have a self-reference if you decide to push it into an array for multiple callbacks
这样做还需要您绑定 object 以便在决定将其推入数组以进行多个回调时拥有自引用
var result = [];
var timeOut;
//...
timeOut = setTimeout(() => {
admin.database().goOffline();
admin.app().delete();
callback(error);
}.bind(this), 2000);
Source: MSDN Function.prototype.bind()来源: MSDN Function.prototype.bind()
If Binding is not a solution and you want a blocking method, you might be interested in a delay function, it behaves the same as a setTimeout but works with promises如果 Binding 不是解决方案并且您想要一种阻塞方法,您可能对延迟 function 感兴趣,它的行为与 setTimeout 相同,但适用于 Promise
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
// Async function solution
await sleep(2000);
console.log('Two seconds later, showing sleep in a loop...');
// non-Async solution
sleep(2000)
.then(()=> {
admin.database().goOffline();
admin.app().delete();
callback(error);
})
.catch(e => console.log(e));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.