1

I'm a newbie in node.js(firebase functions) and Dialogflow fulfillment, I want to retrieve data in a different directory. first is to check the nearest store, and then check the inventory of the store in a different directory, but I have a problem with return. so how I can fix it?

app.intent('location_checking - yes',(conv)=> {
  var store= database.ref('store');
  var inventory = database.ref('inventory);
  var keystore=[];
  return store.orderByKey().on("child_added", function(snapshot){
    keystore.push(snapshot.key)
  })
  return inventory.child(keystore).on("value", function(snapshot){
    var tomato =snapshot.val().tomato;
    //and then check the nearest store with available stock
  })
})
Prisoner
  • 49,922
  • 7
  • 53
  • 105

1 Answers1

0

You have a few issues, some of them conceptual.

The first is that you're using on() and the "child_added" event. But since this is happening inside an Intent Handler, which only gets triggered when the user has done something, you can't also listen to conventional events and react to them. Instead, you should probably use once() with a "value" event - so you query for the values you want and work with them.

Second is that the Intent Handler expects you to return a Promise if you are doing any asynchronous operations - anything that would require a callback handler, for example. This would require some restructuring in how you make the calls to once(), so they return a Promise, and you take action in a .then() block. Since you can chain Promises together using .then(), you can make multiple calls this way.

I'm not sure that ordering by key will get you the "closest" store, but I'll ignore that for the moment to illustrate the rest of the code.

So that part of your code might look something like

return store.orderByKey().once("value")
  .then( snapshot => {
    // Handle the results
    // ...

    // Make the next query
    return inventory.child( childKey ).once("value");
  })
  .then( snapshot => {
    // Handle the inventory results
  });

You can also do this with async/await by making your Intent Handler an async function and then calling await on the database calls. Possibly something like.

app.intent('location_checking - yes', async (conv) => {
  const store= database.ref('store');
  const inventory = database.ref('inventory);

  //...

  const storeSnapshot = await store.orderByKey().once("value");
  // Do something with the store snapshot

  const inventorySnapshot = await inventory.child( childKey ).once("value");
  // Do stuff with the inventory snapshot
})
Prisoner
  • 49,922
  • 7
  • 53
  • 105
  • thank you @Prisoner about the insight. I'm sorry about the uncomplete code. the first is to calculate the distance between user coordinate and store coordinate. after the closest store has found and then check the user's shopping list. and then the user receives a summary of the order at the closest store. looks like using await and async can do the process, but I still didn't know how to use that. – Maulana ahmad Aug 15 '20 at 01:09
  • It isn't clear what your question is at this point. If an answer has addressed your problem, or gotten you on track, upvoting or accepting it is always appreciated. If you still have issues, update your original question with as much information as you can. – Prisoner Aug 15 '20 at 02:05