使用Firebase监听嵌套更改的正确方法是什么?

时间:2016-04-27 13:03:03

标签: javascript firebase

背景:

我正在尝试使用Firebase,Twilio和Node.js通过浏览器发送短信。我在Firebase中的当前数据结构如下所示:

{ messages :
  { +15553485 :
    { FB-GENERATED-KEY-1 :
      { body: "hello world"
        timestamp: 1461758765472 }
    },
    { FB-GENERATED-KEY-3 :
      { body: "I love dogs"
        timestamp: 1461758765475 }
      }
    }
  },
  { +15550000 :
    { FB-GENERATED-KEY-2 :
      { body: "goodbye world"
        timestamp: 1461758765473 }
    },
    { FB-GENERATED-KEY-4 :
      { body: "I love cats"
        timestamp: 1461758765476 }
      }
    }
  }
}

当消息通过前端添加到Firebase时,后端需要通知才能通过Twilio发送短信。当后端从手机获得回复时(通过Twilio),它会将其添加到Firebase。

问题:

当我收听线程更改时,我会收到所有针对该电话号码发送/接收的消息。显然后端不想再发送所有消息,所以我只对添加到线程中的最新消息感兴趣。

此外,我似乎无法轻易获得下面有消息的电话号码(密钥)。

我尝试了什么:

ref.child('messages').on('child_added', ...) - 这适用于/messages添加的新电话号码,但Firebase不会通过新的电话号码(密钥)发送,只会发送FB-GENERATED-KEY-2以下的所有内容。

ref.child('messages').on('child_changed', ...) - 这将返回线程中所有消息,而不仅仅是新消息。我可以在服务器上排序并找到最新的消息,但这似乎会很快变得很重 - 如果你发送了数千条消息怎么办?

在根级别存储消息(也称为展平树)并将数字存储为属性可能会起作用,但我将需要使用电话号码作为一种索引以便稍后与其他数据连接(就像外键一样)。

问题:

  • 如何在收听父/messages上的活动而非特定电话号码时才能收到最新消息?
  • 如何在使用child_活动时获取密钥(电话号码)?
  • 这种数据结构是否有意义?

2 个答案:

答案 0 :(得分:3)

您可以通过调用child_added侦听器返回的快照上的key()来获取Firebase密钥。

然后你可以像这样添加另一个嵌套的监听器:

ref.child('messages').on('child_added', function (snapshot) {
    var phone = snapshot.key();
    ref.child('messages').child(phone).on('child_added', function (message) {
        //send SMS
    }, function (error) {

    });
}, function (error) {

});

答案 1 :(得分:0)

Firebase API允许您侦听值的更改或对子级的操作。它没有办法监听 grand 孩子的变化。

在NoSQL数据库中,您经常需要根据应用程序使用它的方式对数据建模。如果我看一下你的具体用例:

  

当消息通过前端添加到Firebase时,后端需要通知才能通过Twilio发送短信。

我在这里看到一个队列:

smsQueue: {
  pushId1: {
    number: "+15553485",
    body: "hello world",
    timestamp: 1461758765472 
  },
  pushId2: {
    number: "+15550000",
    body: "goodbye world",
    timestamp: 1461758765473
  },
  pushId3: {
    number: "+15553485",
    body: "I love dogs",
    timestamp: 1461758765475
  },
  pushId4: {
    number: "+15550000",
    body: "I love cats",
    timestamp: 1461758765476 
  }
}

使用这种结构,你的后端(希望使用firebase-queue)可以从队列中获取每个任务,调用twilio并从队列中删除该项。