简体   繁体   English

Node.js 12.x AWS lambda 不使用 firebase-admin 实时数据库返回

[英]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:我尝试过的事情:

  • Using exports.handler = async function(event) versus exports.handler = function(event, context, callback) ;使用exports.handler = async function(event)exports.handler = function(event, context, callback) ;
  • For the synchronous attempt above I've tried using context.callbackWaitsForEmptyEventLoop = false versus not;对于上面的同步尝试,我尝试使用context.callbackWaitsForEmptyEventLoop = false不是;
  • Using promises versus cascading functions versus stitching a bunch of .then() 's together;使用承诺级联函数将一堆.then()拼接在一起;
  • Using the firebase-admin versus the https module in-conjunction with the Firebase REST API;将 firebase firebase-adminhttps模块与 Firebase REST ZDB97477ACE41 结合使用
  • Using settimeout to fire the callback later versus not;使用settimeout稍后触发回调不是不使用;
  • Setting the GOOGLE_APPLICATION_CREDENTIALS environment variable to my service account credentials versus referencing the file directly in the code;GOOGLE_APPLICATION_CREDENTIALS环境变量设置为我的服务帐户凭据,而不是直接在代码中引用文件;
  • I've even beefed-up the memory and timeout of the Lambda itself to the maximum it can go, as well as cut down the data I want to pull from Firebase to just 1 record. I've even beefed-up the memory and timeout of the Lambda itself to the maximum it can go, as well as cut down the data I want to pull from Firebase to just 1 record.

Responses I've had as-per the attempts above:根据上述尝试,我得到的回应:

  • AWS (the most frequent): Task timed out after 180.10 seconds ; AWS(最频繁): Task timed out after 180.10 seconds
  • AWS ( .then stitching approach): Function completed successfully (but no data was actually processed); AWS( .then拼接方式): Function completed successfully (但实际没有处理数据);
  • Node HTTPS (REST API approach): ETIMEDOUT or ECONNREFUSED ;节点 HTTPS(REST API 方法): ETIMEDOUTECONNREFUSED

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.

相关问题 如何使用firebase-admin模块使用Node.js从Firebase数据库返回有序数据? - How can I return ordered data from Firebase database with Node.js using the firebase-admin module? 将 Node 14.X 程序转换为 AWS Node 12.X Lambda function - Converting a Node 14.X program into an AWS Node 12.X Lambda function AWS Lambda Node 12.X 上的意外令牌 s3 错误 - Unexpected Token s3 error on AWS Lambda Node 12.X firebase JS SDK 包是否与云函数的 Node.js 环境兼容? 为什么要使用 firebase-admin? - Is the firebase JS SDK package compatible with the Node.js environment of a cloud function? Why use firebase-admin? Firebase-admin Firestore node.js 与模块化 v9 js sdk 共享逻辑 - Firebase-admin Firestore node.js share logic with modular v9 js sdk 从node.js中的firebase实时数据库获取数据时如何通过函数返回数据 - how to return data through function when fetching data from firebase realtime-database in node.js 无法连接到 Firebase 实时数据库 (Node.js) - Cannot connect to Firebase Realtime Database (Node.js) 如何在没有Node.js的情况下使用Firebase实时数据库 - How to use firebase realtime database without node.js Firebase 实时数据库 - orderByChild().equalTo() 不返回预期节点 - Firebase Realtime Database - orderByChild().equalTo() does not return expected node 返回使用Node.js实时运行程序的结果? - Return the results of running a program in realtime using Node.js?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM