Firebase一对一聊天应用程序结构并按值获取子项

时间:2016-09-20 11:11:13

标签: firebase firebase-realtime-database nosql

我尝试使用firebase和angular构建一对一聊天应用。我正在使用在firebase文档上推荐的结构,但我在数据检索方面遇到了麻烦。

{
  "chats" : {
    "one" : {
      "lastMessage" : "test"
    }
  },
  "members" : {
    "one" : {
      "rebel" : true,
      "redboy" : true
    }
  },
  "messages" : {
    "one" : {
      "-KS1R6b-1TdVASQL4tj7" : {
        "createdAt" : 1474288450158,
        "text" : "hgagagagaga",
        "userId" : "rebel"
      },
      "-KS1aZxqX3_PpjNdyiA7" : {
        "createdAt" : 1474291191857,
        "text" : "hhh",
        "userId" : "redboy"
      }
    }
  }
}

如何通过firebase查询获取用户'反叛'聊天。或者我应该将chatIds存储在用户的根目录上。

这种结构使我感到困惑,没有WHERE子句

更新:

如果我将chatIds添加到用户的root,这可以解决我的问题,但不确定它是否属实。似乎正确的方式

"users" : {
    "rebel" : {
      "age" : 3,
      "chats" : {
        "one" : true
      },
      "name" : "rbl"
    },
    "redboy" : {
      "age" : 5,
      "chats" : {
        "one" : true
      },
      "name" : "rb"
    }
  }

2 个答案:

答案 0 :(得分:2)

使用Firebase(以及大多数其他NoSQL解决方案)时,您会发现您经常需要根据应用程序的使用方式对数据建模。

您当前的数据结构可让您轻松找到特定聊天室的成员。

从技术上讲,您可以查询以查找特定成员的聊天室:

ref.child('members').orderByChild('rebel').equalTo(true)

但这要求您为每个用户定义一个索引,该索引不会缩放(因为您必须为每个用户手动添加它们):

{
  "rules": {
    "members": {
      ".indexOn": ["rebel", "redboy"]
    }
  }
}

最常见的解决方案是(如前所述)对数据建模以允许您想要的查询。由于您要为每个用户找到聊天室,因此您应该扩展模型以存储每个用户的聊天室:

"memberships" : {
  "rebel" : {
    "one": true
  },
  "redboy" : {
    "one" true
  }
},

如您所见,此处我们保留倒置索引为members

现在,您可以使用以下方式轻松确定用户反叛的房间:

ref.child('memberships/rebel').on('child_added', ...

我看到你在问题中添加了类似的结构。主要区别在于我将其添加为顶级结构。这是Firebase的常见模式,因为它可以更轻松地保护数据并仅检索数据的子集。

为了更加熟悉此事,我建议在NoSQL data modeling上撰写这篇文章。

答案 1 :(得分:0)

是的,您需要将Chat ID存储在用户根目录下,其值为true,以检索所有聊天记录后面的聊天记录。请按照link

进行操作