首页 > 解决方案 > 使用 Google Assistant 从 Firebase 返回数据数组

问题描述

我的firebase数据库的结构是这样的:水果:苹果,5香蕉,6

我想将苹果和香蕉放在一个数组中,这样当我向 Google 助理发出命令时,它会给我苹果 5 和香蕉 6。我拥有的代码如下所示:

 function handleCommand(agent) {
    return admin.database().ref('Fruits').child().once("value").then((snapshot) =>{
        var i;
        var fruitlist=[];

        //puts each snapshot child of 'Fruit' in an array
        snapshot.forEach(function(item) {
            var itemVal = item.val();
            fruitlist.push(itemVal);
        });

        //outputs command in google assistant
        for (i=0; i < fruitlist.length; i++) {
            agent.add(fruitlist[i]);
        }   

    })

默认响应是“不可用”。

我在执行日志中得到以下信息:

Firebase.child 失败。被称为 0 参数。预计至少为 1。

我不知道在 Firebase.child 中放入哪个参数。如果我希望所有水果都由 Google 助理“说出”。下面是我的firebase结构的图片。

在此处输入图像描述

错误如下所示: 在此处输入图像描述

我现在正在做的只是输出水果是在这样的代码中手动输入每个孩子,并在返回语句中删除“.child”: 在此处输入图像描述

这给了我下面的输出,这也是我想看到的,但是使用数组作为我现在使用的解决方案是非常硬编码的: 在此处输入图像描述

标签: javascriptarraysfirebasefirebase-realtime-databaseactions-on-google

解决方案


正如错误消息所暗示的那样,并且正如您所猜测的那样,该child()调用需要一个参数 - 特别是您要从中获取信息的子节点的名称。但是,由于您想要“Fruits”节点的所有子节点 - 您根本不需要指定它。调用只是在child()层次结构中向下导航,但如果您不想导航,则根本不需要导航。

您返回的快照将具有整个对象的值。在某些情况下,这可能非常大,因此一次获取所有内容并不是一个好主意。在你的情况下,它相当小,所以没什么大不了的。

在 JavaScript 方面,您现在可以将该值作为具有属性和值的对象来处理。但是,您的原始代码并没有完全按照您所说的去做-您得到了值,但忽略了名称(即属性名称或键)。您可以通过多种方式迭代对象的属性,但我喜欢获取对象的键,循环它,获取与键关联的值,然后用它“做某事”。

虽然我还没有测试过代码,但它可能看起来像这样:

 function handleCommand(agent) {
    return admin.database().ref('Fruits').once("value").then((snapshot) =>{
        // Get an object with all the fruits and values
        var fruits = snapshot.val();

        // Get the keys for the attributes of this object as an array
        var keys = Object.keys( fruits );

        // Iterate over the keys, get the associated value, and do something with it
        for( var i=0; i<keys.length; i++ ){
          var key = keys[i];
          var val = fruits[key];
          agent.add( `The number of ${key} you have are: ${val}` );
        }

    })

虽然这是(或应该)工作的 Firebase 和 JavaScript,但在 Google 方面的 Actions 方面存在一些问题。

首先,返回的消息可能有一些语法问题,因此使用您的示例,您可能会看到一条消息,例如“您拥有的 Apple 数量为:1”。有一些方法可以解决这个问题,但请记住,我的示例代码只是一个入门示例。

然而,更重要的是,使用字符串调用agent.add()会创建“SimpleResponse”。在 Action 中,每个回复只允许您进行两个简单的回复。因此,虽然这适用于您的示例,但如果您有更多的水果,它将有问题。您可以通过将字符串连接在一起来解决此问题,因此您只需调用agent.add()一次。

最后,您可能希望实际查看一些针对不同表面的其他响应选项。因此,虽然您可能会在扬声器上朗读此列表,但您可能会在带有屏幕的设备上阅读较短的列表并显示包含信息的表格。然而,关于这些的细节可能会更好地作为一个新的 StackOverflow 问题来解决。


推荐阅读