我正在为Android应用创建聊天部分。使用Google Firebase。 以下任务已经完成
创建聊天节点 2.使用两个用户信息分隔特定聊天线程。 3.阅读单个聊天线程的所有消息。
现在我的问题如下。 1.如何通过单个聊天线程检索最后一条消息。 2.如何创建一个数据库,我可以获得未读消息计数器的计数器。
我的聊天数据库和目标的附件如下。
已经完成。
Firebase数据库架构。
现在我如何更容易创建数据库来解决这个问题。
答案 0 :(得分:9)
Firebase拥有自己的用于构建聊天平台的示例项目Firechat。该项目在doc中得到了很好的解释。他们使用的数据结构可以在doc的末尾看到。您可以使用他们的数据结构。但是对于你的情况,你可能没有任何主持人,所以我们可以让它变得简单。
所以,你可以这样组织它:
main-data
|__messageThread (all data about msgs)
| |__threadId (unique id for msg thread)
| |__chatId (unique id for chat msgs)
| |__userId
| |__userName
| |__chatMessage
| |__chatTimestamp
|
|__messageThreadMetadata
| |__threadId
| |__createdAt
| |__createdByUserId
| |__threadId
| |__threadName
| |__threadType (public/private)
| |__lastChatId (id for last chat, use this to lookup in messageThread)
|
|__users
| |__userId
| |__userId
| |__userName
| |__activeThreads (list of ids of active threads used by user)
|
|__unseenMsgCountData
| |__threadId
| |__userId
| |__unseenMsgCount
回到你的问题:
如何在线程中获取最后一条消息?请在线程中使用节点 lastChatId 并使用它来查找相应的 chatMessage < /强>
如何在用户的线程中获取看不见的消息计数?这是一个对每个线程和每个用户都是主观的数据。同一个线程可能有两个或更多用户,每个用户都有不同的看不见的消息计数。因此,您可以使用 unseenMsgCountData ,您可以在其中检查threadId和userId。每当有人发布聊天时,在聊天线程关闭的其他用户的该线程中将看不见的msg计数器递增1(使用用户的 activeThreads 列表来跟踪他是否积极参与线程或不)。不要为他增加计数器,这个msg不是他自己看不见的msg)。当任何其他用户打开该线程时,将该值重置为零。
希望这会有所帮助。如果需要任何进一步的解释或帮助,请在这里敲门。
答案 1 :(得分:3)
这是我的解决方法。
正如您所看到的,我正在为消息制作两个引用,而最近的第二个是用户列表。
每当我点击用户列表并打开我的聊天页面时,在我的聊天页面中,我检查接收者ID的条件并发送状态并计入聊天页面的onCreate()中的最近参考,就像这样。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
uid = pref.getString("uid", null);
sender_name = pref.getString("first_name", null);
Bundle bundle = getIntent().getExtras();
if(bundle != null && !bundle.isEmpty()){
recevier_name = bundle.getString("uname");
receiver_id = bundle.getString("UserId");
}else {
recevier_name = "Admin";
receiver_id = "1";
}
chat_date = listAdapter.SIMPLE_DATE_FORMAT.format(new Date().getTime());
if (Integer.parseInt(uid) < Integer.parseInt(receiver_id)) {
value = String.valueOf(uid + "--*--" + receiver_id);
} else {
value = String.valueOf(receiver_id+"--*--"+uid);
}
myRef1 = database.getReferenceFromUrl("https://firebaseio.com/messages/"+value);
myRef2 = database.getReferenceFromUrl("https://firebaseio.com/recents/"+value);
myRef2.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot != null){
Map map1 = (Map) dataSnapshot.getValue();
if(map1 != null){
String rec_id = (String) map1.get("recever_id");
if(rec_id.equals(uid)){
myRef2.getRef().child("count").setValue("0");
myRef2.getRef().child("status").setValue("online");
}
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
getChat();
}
所以每当我打开聊天时,如果receiver_id是my_id,我的状态就是在线。
现在在聊天按钮中单击我检查是否状态不在线,如此。
private ImageView.OnClickListener clickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if(v==enterChatView1)
{
message_text = chatEditText1.getText().toString();
final Map<String, String> map = new HashMap<String, String>();
map.put("sender_id", uid );
map.put("recever_id", receiver_id);
map.put("sender_name", sender_name);
map.put("recevier_name", recevier_name);
map.put("text", message_text);
map.put("text_id", uid);
map.put("date", chat_date);
myRef1.push().setValue(map);
// myRef2.setValue(map);
// sendMessage(chatEditText1.getText().toString(), chat_date, UserType.OTHER);
myRef2.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot != null){
Map map1 = (Map) dataSnapshot.getValue();
if(map1 != null){
String status = (String)map1.get("status");
if(map1.containsKey("count")){
if(!status.equals("online")) {
String count = (String) map1.get("count");
int val = Integer.parseInt(count);
map.put("count", String.valueOf(++val));
map.put("status", "offline");
myRef2.setValue(map);
Log.d("VALUE", "YES" + val);
}else {
map.put("count", String.valueOf(0));
map.put("status", "online");
myRef2.setValue(map);
Log.d("VALUE", "No");
}
}else {
map.put("count", String.valueOf(1));
map.put("status", "offline");
myRef2.setValue(map);
Log.d("VALUE", "No");
}
}else {
map.put("count", String.valueOf(1));
map.put("status", "offline");
myRef2.setValue(map);
Log.d("VALUE", "first time");
}
}else {
map.put("count", String.valueOf(1));
map.put("status", "offline");
myRef2.setValue(map);
Log.d("VALUE", "first time");
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
chatEditText1.setText("");
}
};
最后关闭聊天页面时。在onBackPress()事件中将状态离线添加到最近,就像这样。
@Override
public void onBackPressed() {
myRef2.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot != null){
Map map1 = (Map) dataSnapshot.getValue();
if(map1!= null){
String rec_id = (String) map1.get("recever_id");
if(rec_id.equals(uid)){
myRef2.getRef().child("count").setValue("0");
myRef2.getRef().child("status").setValue("offline");
}
}
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
finish();
this.overridePendingTransition(R.anim.left_in,
R.anim.left_out);
}
答案 2 :(得分:1)