1

I am using Firebase Cloud Function as fulfilment for my DialogFlow Google Assistant Action, but I need to retrieve data from the Firebase Database before I manage the intent. Here's a code snippet:

  var userDataRef = sessionDatabaseRef.child(sessionId);
  userDataRef.once("value").then(function(data) {
    console.log(data.val());
    handleIntentAndProcessResponse();
  }).catch(function(){
    console.log("No data yet for this session");
    handleIntentAndProcessResponse();
  });

The function called handleIntentAndProcessResponse is where the intent logic returns the response by setting the conv.ask(new SimpleResponse(blah)) stuff. When I test this it fails and the Cloud Function log gives me this error:

Error: No response has been set. Is this being used in an async call that was not returned as a promise to the intent handler?

So, how can I handle this async call to the Firebase database so it waits for the response? I need to use the data it returns when I handle the intent.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Lee Probert
  • 10,308
  • 8
  • 43
  • 70

1 Answers1

1

As the error message suggests, you need to return the Promise itself so the dispatcher knows it needs to wait for every part of the async operation to be completed.

Fortunately, the calls to userDataRef.once().then().catch() will evaluate to a Promise, and you can just return this. So this should be good

  return userDataRef.once("value").then(function(data) {
    console.log(data.val());
    handleIntentAndProcessResponse();
  }).catch(function(){
    console.log("No data yet for this session");
    handleIntentAndProcessResponse();
  });
Prisoner
  • 49,922
  • 7
  • 53
  • 105
  • thank you so much. This worked. One further question: I am having to store data between sessions because I was using a global class to do this before I realised that Cloud functions share instances between invocations, and my data was being overwritten by other sessions. Do I need to worry about a race condition with this class? Can I just update it with the session data from Firebase when I handle the intent? – Lee Probert Mar 10 '20 at 22:21
  • I think I'm correct in thinking that it wont allow multiple invocations of the function instance simultaneously. – Lee Probert Mar 10 '20 at 22:24
  • You're correct that cloud functions may share instances between invocations, or you may get totally separate instances. Your best case to make sure you address any questions you have about this is to create a new StackOverflow question with exactly how you want to preserve the session info (there are a number of questions and answers discussing this already) and where your concerns are if those other questions/answers still leave you with uncertainty. – Prisoner Mar 10 '20 at 22:39