Angular2 Firebase,聊天应用程序

时间:2017-05-03 06:50:10

标签: angular firebase firebase-realtime-database angularfire2

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

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

但目前我只能从一个user_id中选择消息。

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

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

所以我的问题是,如何选择"来自" user_1和user_2的字段名称?由于Firebase不支持WHERE子句,因此对我来说是一个挑战(

1 个答案:

答案 0 :(得分:2)

创建另一个字段,其中包含“from”userId和“to”userId以及对该字段的查询

如果我理解正确,您想要显示一个用户,例如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片段,但是从 fromTo 字段开始。

分隔符

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

from: chris
to: topher
fromTo: christopher

from: christ
to: opher
fromTo: christopher

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

其他索引字段

如果你需要收到相反方向的信息(即Sharon to Jim),我可以想到两个解决方案:

  1. 为Sharon * Jim和Jim * Sharon
  2. 做一个查询
  3. 创建另一个字段 fromToSorted ,在合并它们之前按字母顺序对两个userId进行排序,这样两个通信方向将产生相同的值,Jim * Sharon。
  4. 这显然可以扩展为包含您可能希望搜索或排序的每个组合的额外字段。

    在哪里这样做?

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

    想要对值可以更改的字段使用此方法的读者可能希望将创建这些额外字段的代码生成为可以在创建原始字段时调用的函数,也可以已被编辑。

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

    是。规范化的这一政策来自数据存储更加昂贵的时代,人们愿意等待计算机处理多个表格来回答问题。现在,对于您描述的任务类型,数据存储非常便宜,人们希望快速响应。因此,在Firebase和其他NoSQL数据库中,我们很乐意对数据进行反规范化,这有助于实现时间紧迫的任务。

    最后一个警告:规范化的第二大好处是,如果每个数据项,例如消息“from”字段只存储一次,我们的软件不可能偶然只更新一个副本而不能更新另一个副本。因此,当我们对数据库进行非规范化时,正如我在本回答中所描述的那样,我们必须非常严格地确保所有额外的字段(这里只是 fromTo fromToSorted 字段每当更新时都会更新。