I'm building an Alexa Skill, which requires me to listen to a Firebase Realtime Database. In one particular part of the skill, I need to write a JSON object to Firebase, consisting of two fields, "intent", with an insignificant value, and "done", with a value of false
.
Then, I wait for another device listening to this database to register this change, at which point it creates another field, named "result", with some numerical value, and changes the value of "done" to true.
Then the original function (test1
) should recognize when the value of "done" is true, and then retrieve the value of "result".
What I'm having trouble with is coming up with a function that does all of these read/write operations before my main (asynchronous) function finishes. As the title suggests, AWS Lambda times out for some reason, and I am unable to read the value of "result".
This is the function I'm using:
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 output of the console (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 structure of the Firebase data:
"done" is initially false. When the other device add "result", it also updates the value of "done" to true. "148434459..." is targetRef.
Your help is truly appreciated. I will supply more info if needed.
The problem is that on
does not return a promise. Instead, it returns the callback function that was passed as a parameter. on
will invoke the callback for the initial data and then again for any changes made to the data.
You most likely want to use once
, which does return a promise:
...
}).then(function () {
return targetRef.orderByChild("done").equalTo(true).once("value");
}).then(function (snapshot) {
snapshot.forEach(function (childSnapshot) {
console.log(childSnapshot.val());
});
})
...
Note that the promise's resolved snapshot will contain zero or more children that matched the query. To enumerate the children, you can use the snapshot's forEach
method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With