javascript - Node.js 12.x AWS lambda 不使用 firebase-admin 实时数据库返回
问题描述
我已经在这个问题上卡了几天了,几乎没有进展,如果可以的话,请帮忙!
我有一个 Node.js (v12) AWS Lambda,它需要从我的 Firebase 实时数据库中提取数据,并将每条记录处理到 Redis 缓存中(如果它不存在)。该函数启动但从未完成,而是Task timed out after 180.10 seconds
从 AWS 接收。
我尝试过的事情:
- 使用
exports.handler = async function(event)
与exports.handler = function(event, context, callback)
; - 对于上面的同步尝试,我尝试过使用
context.callbackWaitsForEmptyEventLoop = false
与不使用; - 使用 Promise与级联函数与将一堆
.then()
's 拼接在一起; - 将
firebase-admin
vs模块与https
Firebase REST API 结合使用; - 用于稍后
settimeout
触发回调而不是不触发; - 将
GOOGLE_APPLICATION_CREDENTIALS
环境变量设置为我的服务帐户凭据,而不是直接在代码中引用文件; - 我什至将 Lambda 本身的内存和超时时间增加到了它可以达到的最大值,并将我想从 Firebase 提取的数据减少到只有 1 条记录。
根据上述尝试,我得到的回应:
- AWS(最常见的)
Task timed out after 180.10 seconds
:; - AWS(
.then
拼接方法):(Function completed successfully
但没有实际处理数据); - 节点 HTTPS(REST API 方法):
ETIMEDOUT
或ECONNREFUSED
;
下面是我的目标,但仍然没有运气。我已经删除了缓存代码,因为我知道它可以正常工作。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);
}
};
解决方案
您似乎没有在函数的根级别存储或使用 setTimeout 。您应该存储它,以便回调函数可以继续运行,因为它只存在于范围内。这样做还需要您绑定对象,以便在决定将其推入数组以进行多个回调时拥有自引用
var result = [];
var timeOut;
//...
timeOut = setTimeout(() => {
admin.database().goOffline();
admin.app().delete();
callback(error);
}.bind(this), 2000);
来源:MSDN Function.prototype.bind()
如果 Binding 不是解决方案并且您想要一个阻塞方法,您可能对延迟函数感兴趣,它的行为与 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));
推荐阅读
- python - 找不到版本
- svn - SVN“...已经是不同 URL 的工作副本”问题和额外的 .svn 问题
- amazon-web-services - 使用 AWS Lambda 进行端口转发?
- javascript - 升级到 React Native 0.55.4 后,isMounted() 警告一直显示
- c++ - 如何使用 MFC 从 firefox 获取 url 但不使用 DDE?
- ios - 斯威夫特 UIActivityViewController
- ruby-on-rails - 未初始化的常数 Degree(error)
- android - 找不到 com.google.android.gms.internal.zzbck 无法访问 zzbck 类文件
- kafka-consumer-api - 卡夫卡寻求抵消部分工作
- asp.net-mvc - 如何在 reactjs 中编写 onclick 事件?