英文:
Chats aren't being added to the ArrayList even though I can see that they are being saved to Firebase
问题
这是你提供的内容的翻译:
希望有人能够帮我解决这段代码的逻辑问题。我正在尝试实现一个聊天功能,按照我设定的方式,它似乎应该可以正常工作和流畅运行(如果不行,有人请告诉我如何改进),但无论如何,我可以看到聊天消息被添加并成功保存到 Firebase
中,但问题是它们不会被添加到 ArrayList
中,因此用户无法看到他们与他人收发的聊天消息。
有人能告诉我我的代码哪里出错了,以便我可以修复它吗?
按照我设定的方式,这不是一个糟糕的流程,对吗?
MessagesActivity:在这里,我将聊天消息添加到 Firebase 中
final DatabaseReference chatReference = FirebaseDatabase.getInstance().getReference("Chat List").child("Sender").child(mFirebaseUser.getUid()).child("Receiver").child(mId);
chatReference.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if (!dataSnapshot.exists()) {
chatReference.child("Receiver").setValue(mId);
chatReference.child("Timestamp").setValue(ServerValue.TIMESTAMP);
chatReference.child("Sender").setValue(mFirebaseUser.getUid());
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
final DatabaseReference chatReferenceReceiver = FirebaseDatabase.getInstance().getReference("Chat List").child("Receiver").child(mId).child("Sender").child(mFirebaseUser.getUid());
chatReferenceReceiver.child("Receiver").setValue(mId);
chatReferenceReceiver.child("Timestamp").setValue(ServerValue.TIMESTAMP);
chatReferenceReceiver.child("Sender").setValue(mFirebaseUser.getUid());
ChatFragment:在这里,聊天消息应该被添加到 ArrayList 中
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Chat List").child("Sender").child(mFirebaseUser.getUid()).child("Receiver");
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
mChatList.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Chatlist chatlist = snapshot.getValue(Chatlist.class);
mChatList.add(chatlist);
}
if (mChatList.size() == 0) {
mNoMessages.setVisibility(View.VISIBLE);
} else {
mNoMessages.setVisibility(View.GONE);
chatList();
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
(代码部分已被翻译,图片部分已被省略。)
英文:
Was hoping that someone could help me out with the logic for this code. I am trying to implement a chat, and the way that I have it set up it seems like it should work and flow well (if not, someone tell me how to make it better), but anyways, I can see that the chats are being added and saved to Firebase
just fine, but the problem is they don't get added to the ArrayList
for some reason so that the user can see the chat that they have sent or received from someone else.
Can someone tell me which part of my code I have wrong so that I can fix it?
That's not a bad flow the way I have it set up, is it?
MessagesActivity Here I add the chats to Firebase
final DatabaseReference chatReference = FirebaseDatabase.getInstance().getReference("Chat List").child("Sender").child(mFirebaseUser.getUid()).child("Receiver").child(mId);
chatReference.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
if (!dataSnapshot.exists()) {
chatReference.child("Receiver").setValue(mId);
chatReference.child("Timestamp").setValue(ServerValue.TIMESTAMP);
chatReference.child("Sender").setValue(mFirebaseUser.getUid());
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
final DatabaseReference chatReferenceReceiver = FirebaseDatabase.getInstance().getReference("Chat List").child("Receiver").child(mId).child("Sender").child(mFirebaseUser.getUid());
chatReferenceReceiver.child("Receiver").setValue(mId);
chatReferenceReceiver.child("Timestamp").setValue(ServerValue.TIMESTAMP);
chatReferenceReceiver.child("Sender").setValue(mFirebaseUser.getUid());
ChatFragment Here the chats should be added to the ArrayList
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("Chat List").child("Sender").child(mFirebaseUser.getUid()).child("Receiver");
reference.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
mChatList.clear();
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
Chatlist chatlist = snapshot.getValue(Chatlist.class);
mChatList.add(chatlist);
}
if (mChatList.size() == 0) {
mNoMessages.setVisibility(View.VISIBLE);
} else {
mNoMessages.setVisibility(View.GONE);
chatList();
}
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
答案1
得分: 0
所以谷歌是你的朋友。其他人过去在这方面曾经遇到过困难,并且有关于这个问题的文章/帖子,比如在 Medium、Stack Overflow 上,提供了一些想法。我喜欢并且使用的一个方法 - 没有羞于从他人的优秀工作中借鉴 - 就在这篇 Medium 文章中:https://medium.com/@ngengesenior/database-structure-of-one-to-one-chat-app-with-firebase-93f813184dfe
它涵盖了 Firestore 和 RTDB。基本上,对于 RTDB,你的聊天列表是使用两个用户 ID 的连接(复合)键来管理的,这两个用户 ID 在创建键之前按字母顺序排序,例如 userid1 = xxxx,userid2 = bbbb,复合键是 bbbbxxxx(FB 用户 ID 为 28 个字符,因此复合键为 56 个字符)。
通过这种方式,通过一次数据库读取复合键,你可以获得这两个用户之间的所有聊天消息,无论哪个是发送者,哪个是接收者。你在消息上保留一个布尔指示器,用于表示复合键中的第一个用户 ID 是否是发送者,通过这个信息,你可以解析复合键以确定发送者和接收者的用户 ID - 这是我对文章中描述的内容的改进,他仍然将发送者和接收者的 ID 存储为属性。这消除了大量的数据重复,并应该简化处理聊天所需的代码。我不使用 Java,所以无法帮助你编写代码。
英文:
So Google is your friend here. Others have struggled with this in the past and there are articles/posts on eg. Medium, SO that give ideas. The one I liked and used - no shame in copying the good work of others is in this Medium post: https://medium.com/@ngengesenior/database-structure-of-one-to-one-chat-app-with-firebase-93f813184dfe
It covers both Firestore and RTDB. Basically, for RTDB your list of chats is managed using a concatenated (compound) key of both userids, the two userids being sorted alphabetically before creating the key eg. userid1 = xxxx, userid2 = bbbb, compound key is bbbbxxxx (FB userids are 28 chars long so the compound key is 56 chars).
In this way, with one database read to the compound key you get all the chat messages between those two users, no matter which one was the sender or receiver. You keep a bool indicator on the message to say if the first userid in the compound key was the sender and with that information you can parse the compound key to determine the userid of the sender and receiver - that was my improvement over what is described in the article, he still stored the sender and receiver ids as properties. Cuts out a huge amount of data duplication and should simplify the code needed to handle chats. I don't use Java so can't help you with the code.
专注分享java语言的经验与见解,让所有开发者获益!
评论