我正在尝试创建“针对Android的一对一Firebase数据库聊天”。到目前为止,正在使用下面的结构。大字符串表示user_TO_user,KW记录是聊天消息。
chat
D_57f337e7e55df9ca167d0421_TO_O_57f337e7e55df9ca167d0421
-KWd06dvkmcoCJd6fNWs
-KWd7yBoUy-RkEJAlVOB
-KWd8Au5bPAwMsx3gYhp
....
O_57f337e7e55df9ca167d0421_TO_D_57f337e7e55df9ca167d0421
-KWd06da-Cx0qjnPUE3l
-KWd7yBvyLoLd2fiBcia
-KWd8Au3A_5FJZS8S0qz
....
在显示特定用户对话列表的Android活动中,我创建了一个ListView并从Firebase中读取列表:
String calculated = "O_57f337e7e55df9ca167d0421"; // calculated userId
firebase_chat.orderByKey().startAt(calculated).endAt(calculated + "\uf8ff").addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s)
{
// add item to list adapter
}
}
这很好。
但我在这里有两个问题。
第一即可。我需要制作具有反向名称的节点的副本(如上所示,即A_TO_B和B_TO_A),以允许参与聊天的两个用户使用Firebase数据库查询功能(因为substring()或contains()不是Firebase中的可用过滤器)。有没有更好的查询方法阻止我复制所有消息?是否有任何节点别名?
第二即可。节点名称本身有助于代码识别聊天名称....但它对用户表示没有任何帮助。我需要将某个用户O_57f337e7e55df9ca167d0421与“John Smith”关联起来,以便在屏幕上显示John Smith。此机制应该应用于每个会话节点。
我在考虑使用每个节点中的第一条记录来存储节点元数据,因此,在获取节点名称后,我可以从Android设备查询DataSnapshot以查找有关此节点的信息。但是,我担心这会触发每个会话节点的新后端(Firebase DB)请求以获取其元数据,这可能效率不高并导致来自每个设备的服务器调用过多。正确的解决方案是在每个节点的名称中加入元数据 ...所以我可以保存第二次调用....但这在Firebase中似乎不可行。
你是否想出更有效的方法?
由于
更新:所以,根据vzsg的回答,更好的结构可能是:
这将允许:
在打开对话屏幕时创建聊天条目
在第一条消息上创建一个msgs条目
查询聊天/节点查找用户的对话,包括其他用户的数据
查询msgs / A_TO_B节点以获取会话的实际消息
(我会稍等一下接受你的回答,但我喜欢这个提议)
update2:或简化聊天节点:
并以对话方式撰写会话名称以获取消息
我在此描述的最终解决方案:https://github.com/cvivek07/Firebase_Chat/issues/1#issuecomment-260925121
答案 0 :(得分:2)
有一种非常简单的方法可以避免重复:在计算组合ID时按字典顺序对两个用户ID进行排序。 这样,无论哪个用户正在寻找另一个用户,他们都会找到一个单一的对话而你不必跳过篮球。
E.g:
也就是说,没有任何查询选项可以提供帮助,并且根本不支持别名节点。
您有两种不同的利弊选择:
将参与者用户名复制到聊天节点中,即您创造的“正确解决方案”。它不一定是真的,但它是可行的:存储是便宜的,并且消除额外的查询使客户端代码更简单。但是,当用户更改其名称时,拥有副本会导致问题 - 所有相关的聊天节点也应该更新。
将用户节点保留在其他位置,并懒惰地获取它们以加载用户名(以及可能的其他配置文件数据,如图片URL)。显示列表变得更难实现,但只需要在一个地方进行更新 您不必担心“服务器请求太多”,但这是SDK可以轻松处理的内容。您还可以在内存中缓存已知用户。
这两种解决方案都在实践中运行,您必须确定哪种策略在您的方案中更有效。
所呈现的架构存在严重缺陷:当您使用chat
节点列出会话然后列出其下的消息时,客户端必须下载所有内容,包括每条消息都没有界限,浪费了大量的CPU时间和带宽。
您应该考虑单独存储会话列表和消息;一般而言,旨在建立平坦的数据库结构。
答案 1 :(得分:1)
添加一些代码以支持 vzsg
创建的第1点{{1}}
最终为聊天室中的参与者制作一个UID