首页 > 解决方案 > Node.js 12.x AWS lambda 不使用 firebase-admin 实时数据库返回

问题描述

我已经在这个问题上卡了几天了,几乎没有进展,如果可以的话,请帮忙!

我有一个 Node.js (v12) AWS Lambda,它需要从我的 Firebase 实时数据库中提取数据,并将每条记录处理到 Redis 缓存中(如果它不存在)。该函数启动但从未完成,而是Task timed out after 180.10 seconds从 AWS 接收。

我尝试过的事情:

根据上述尝试,我得到的回应:

下面是我的目标,但仍然没有运气。我已经删除了缓存代码,因为我知道它可以正常工作。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);
    }
};

标签: javascriptnode.jsfirebase-realtime-databaseaws-lambdafirebase-admin

解决方案


您似乎没有在函数的根级别存储或使用 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));

推荐阅读