Angular2 Firebase,聊天应用程序

Angular2 Firebase, Chat Application

我目前正在尝试在我的 Angualar2 应用程序中实现私人聊天消息传递。目前我正在使用 AngularFire2 来处理 firebase。 我的消息的结构如下:

Messages
  message_id_0
    from: user_id_0
    to:   user_id_1
    type: "private"
    message: "a private message"

但目前我只能 select 来自一个 user_id 的消息。

this.af.database.list('messages', {
          query: {

              orderBy: "from",
              equalTo: auth.uid,
...

所以我的问题是,如何 select 所有带有 "from" 字段名称的消息 user_1 和 user_2 ?由于 Firebase 不支持 WHERE 子句,这对我来说是一个挑战(

创建另一个由 "from" 用户 ID 和 "to" 用户 ID 组成的字段,并查询该字段

如果我没理解错的话,你想显示一个用户,例如Jim,Jim 和特定其他用户之间的所有消息,例如沙龙。最简单的方法是在数据中创建一个新字段。

Messages
  message_id_0
    from: user_id_0
    to:   user_id_1
    fromTo: user_id_0 * user_id_0        // <------- added field
    type: "private"
    message: "a private message"

// e.g. An example dataset might be:

Messages
  message_id: 5903784520934857403
    from: Jim
    to: Sharon
    fromTo: Jim*Sharon
    type: "private"
    message: "whatever"

然后你可以使用你的 angularfire 片段,但是 orderBy fromTo 字段。

分隔符

值得在 userId 之间使用分隔符(这里我使用了星号),因为如果不这样做,可能会发生意外冲突,例如这两对不同的用户将具有相同的 fromTo 值:

from: chris
to: topher
fromTo: christopher

from: christ
to: opher
fromTo: christopher

如果它们有分隔符,例如“*”,那么 fromTo 会变得不同。确保使用不能出现在 userId 中的字符。

其他索引字段

如果您还需要接收反方向的消息(即 Sharon 到 Jim),我可以想到两个解决方案:

  1. 对 Sharon*Jim 进行一个查询,对 Jim*Sharon 进行另一个查询
  2. 创建另一个字段 fromToSorted,在其中按字母顺序对两个 userId 进行排序,然后再合并它们,这样双向通信将产生相同的值,Jim*Sharon。

这显然可以扩展为包含一个额外的字段,用于您可能希望搜索或排序的每个组合。

在哪里做这个?

在程序中创建这些额外字段的逻辑位置是在创建消息的位置。在您的示例问题中,您选择索引的字段是其值在创建后无法更改的字段。

希望对值 可以 更改的字段使用此方法的读者可能希望将创建这些额外字段的代码制作成一个函数,只要原始字段已创建或可能已被编辑。

这不是违反不多次存储相同数据的政策吗?

是的。 Normalization 的那个策略来自数据存储更昂贵的时代,人们愿意等待计算机处理多个表以吐出答案。现在,对于您描述的任务类型,数据存储非常便宜,而且人们希望快速响应。因此,在 Firebase 和其他 NoSQL 数据库中,我们很乐意对数据进行非规范化,这有助于完成对时间要求严格的任务。

最后一个警告:规范化的第二大好处是如果每个数据项,例如message "from" 字段只存储一次,我们的软件不可能不小心只更新一个副本而不更新另一个副本。因此,当我们对数据库进行非规范化时,正如我在这个答案中所描述的,我们必须绝对严格地确保所有额外的字段(这里只是 fromTofromToSorted 字段)在更新 fromto 时更新。