title: dialogflow fullfilment and firebase response time
body: <p>I am trying to build a simple chatbot with <code>DialogFlow</code>. </p>
  
  <p>My aim is to give information from user question, like : where can I slackline above water in croatia ? I have two parameters (<code>croatia</code>, <code>waterline</code>) and a list of slackline places.</p>
  
  <p>So I need a data base to retrieve information from parameters. DialogFlow allows fulfillment with <code>Firebase</code>. I build a database with places (name, country, type of slack) and enable <code>webhook</code> call for my intent.</p>
  
  <p>I use Inline Editor and <strong>index.js</strong></p>
  
  <pre><code>const parameters = request.body.queryResult.parameters;
  var country = parameters.country.toString();
  
  function show(snap) {
     console.log('snap');
     agent.add(JSON.stringify(snap.val(),null,2));
  }
  
  function slkplc(agent) {
       var testRef;
       firebase.database().ref('slackplace').once('value',show);
  }
  
  // Run the proper function handler based on the matched Dialogflow intent name
  let intentMap = new Map();
  intentMap.set('slack place', slkplc);
  agent.handleRequest(intentMap);
  </code></pre>
  
  <p>But I do not get the expected result while trying it on DialogFlow or Google Assistant. The function show is asynchronously called but too late and the response is not available for <strong>DialogFlow</strong> :</p>
  
  <p><img src="https://i.stack.imgur.com/01nhD.png" alt="firebase log"></p>
  
  <p>I see three way to deal with this problem :</p>
  
  <ol>
  <li>use blocking call to database : another database ?</li>
  <li>treat asynchronous message with DialogFlow ???</li>
  <li>response to user that an error occured.</li>
  </ol>
  
  <p>The third that I choose, but it is always on error.</p>
  
  <p>After trying several things to wait data from database response, the only thing I managed is to freeze the response, therefore the timeout of DialogFlow - 5s -and Firebase - 60s - were reached.</p>
  
  <p><strong>A workaround</strong></p>
  
  <p>Another way to do it is to separate database acquisition and request/response from DialogFlow. The data of database is collected outside of the <code>dialogflowFirebaseFulfillment</code></p>
  
  <pre><code>var data;
  var inidata = firebase.database().ref().on('value',function(snap) {
       console.log('snap');
       data = snap.val();
   });
  
  exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) =&gt; {
   const agent = new WebhookClient({ request, response });
   ...
   function slkplc(agent) {
       agent.add(JSON.stringify(data,null,2));
   }
  
    // Run the proper function handler based on the matched Dialogflow intent name
    let intentMap = new Map();
    intentMap.set('slack place', slkplc);
    agent.handleRequest(intentMap);
  }
  </code></pre>
  
  <p>Now I can do what I want with data, and I am able to find the place where I can practice waterline in croatia. But there is always something weird, the data of the database is duplicated ...</p>