Listening to the Firebase Database in AWS Lambda

I am creating an Alexa skill that requires me to listen to the Firebase Realtime database. In one specific part of the skill, I need to write a JSON object for Firebase, consisting of two fields "intention", with a slight value and "done" with a value of false .

Then I wait until another device listens to this database to register this change, after which it creates another field called "result" with some numerical value and changes the value of "done" to true.

Then the original function ( test1 ) should recognize when the value β€œdone” is true, and then get the value β€œresult”.

I am having problems with the application of a function that performs all these read / write operations until the completion of my main (asynchronous) function. As the name suggests, AWS Lambda for some reason does not work, and I can not read the meaning of "result".

This is the function I use:

 function test1(intentName, targetRef, context) { console.log("writing"); targetRef.set({ intent: intentName, done: false }).then(function() { return targetRef.orderByChild("done").equalTo(true).on("value"); }).then(function(snapshot) { var res = snapshot.val().result; console.log("Res: " + res); context.succeed( //context.succeed should be called after "result" has a value. generateResponse( buildSpeechletReponse("The result is" + processNumbersForSpeech(res), true), {} ) ); }); } 

This is the console output (in AWS Lambda):

   20:05:31 START RequestId: a25d2354-d9cb-11e6-b80a-f35142a5f45f Version: $LATEST 20:05:31 2017-01-13T20:05:31.464Z a25d2354-d9cb-11e6-b80a-f35142a5f45f writing  20:05:35 END RequestId: a25d2354-d9cb-11e6-b80a-f35142a5f45f  20:05:35 REPORT RequestId: a25d2354-d9cb-11e6-b80a-f35142a5f45f Duration: 4001.15 ms Billed Duration: 4000 ms Memory Size: 128 MB Max Memory Used: 39 MB  20:05:35 2017-01-13T20:05:35.335Z a25d2354-d9cb-11e6-b80a-f35142a5f45f Task timed out after 4.00 seconds 

The following is the data structure of Firebase:

enter image description here

"done" is initially false. When another device adds a "result", it also updates the value "done" to true. "148434459 ..." - targetRef.

Your help is really appreciated. If necessary, I will supply additional information.

+5
source share
5 answers

The problem is that on does not return a promise. Instead, it returns a callback function that was passed as a parameter. on will call a callback for the source data, and then again for any changes made to the data.

You most likely want to use once , which returns a promise:

 ... }).then(function () { return targetRef.orderByChild("done").equalTo(true).once("value"); }).then(function (snapshot) { snapshot.forEach(function (childSnapshot) { console.log(childSnapshot.val()); }); }) ... 

Please note that a promise snapshot will contain zero or more children that match the query. To list the children, you can use the forEach snapshot method.

+1
source

I found that initializing firebase in a lambda function (for example, via firebase-admin) will prevent the function from ending (before the default 6-second timeout) if you do not call app.delete() on the firebase application instance. In addition, you must make sure that every time you run your lambda function, you use a new instance of the Firebase application, otherwise you will run into problems.

 const app = admin.initializeApp({}); app.database().ref('child').set('hello').then(() => { return app.delete(); }).then(() => { let response = {}; // whatever callback(null, response); }); 
+1
source

Your lambda function probably expires after 4 seconds because you set this value when setting up the lambda function. In order for your function to wait for the appearance of an external thing, you can schedule the function to regularly request a value using setTimeout () until the value appears. If it takes more than 4 seconds, you also need to increase the waiting time for functions.

0
source

From the AWS Lambda documentation:

Q: How long can the AWMS Lambda function run?

All calls made to AWS Lambda must be completed within 300 seconds. The default timeout is 3 seconds, but you can set the timeout to any value from 1 to 300 seconds.

I would suggest that you have problems trying to wait for Firebase events from inside the Lambda function. Lambda is designed to call data and process and exit data, not to wait for other events. You will be better off using some kind of VPS and running a generic Node process to work with the database. Firebase's pushing data lambda is fine, but what you are trying to achieve with Firebase might be wrong.

0
source

You call a function before calling another function. Try npm sleep () or setTimeout () to pause your function.

-1
source

Source: https://habr.com/ru/post/1262772/


All Articles