我有一个聊天应用程序,仅使用Firebase Realtime数据库实体实现。没有特定的消息传递组件。
我正在为存储消息的聊天实体(或表)添加一个侦听器。侦听器是由addChildEventListener添加的,该方法应调用onChildAdded方法,以在附加聊天时和添加消息时从聊天实体中带走所有子级。
问题是,当我创建表,发送第一条消息并附加侦听器时,我可以在Firebase控制台上看到正在创建的表和消息,但是onChildAdded方法没有被调用,但是很多时间之后才被调用。然后,一经调用,有时会超过5分钟,我就能按预期发送和接收消息。
是什么原因导致这种长时间的延迟?
我已经尝试在创建要侦听的表之后立即设置侦听器,但是没有用。
创建聊天实体(表)
final DatabaseReference chat = dbReference.child("chat");
final DatabaseReference user = dbReference.child("user");
chatId = chat.push().getKey();
Log.d("mymessages", "createChat(), chatId = " + chatId);
HashMap newChatMap = new HashMap();
newChatMap.put("id", chatId);
newChatMap.put("users/" + currentUserId, true);
newChatMap.put("users/" + userId, true);
// Creating chats table
chat.child(chatId)
.child("info")
.updateChildren(newChatMap);
Log.d("mymessages", "Chat table created.");
创建消息并将其插入聊天实体
DatabaseReference newMessageDb = dbReference.child("chat").child(chatId).push();
Log.d("mymessages", "message created.");
Map newMessageMap = new HashMap<>();
newMessageMap.put("text", editTextMessage);
newMessageMap.put("creator", currentUserId);
newMessageDb.updateChildren(newMessageMap);
Log.d("mymessages", "message's text and creator added.");
添加收听者
dbReference.child("chat").child(chatId).addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
if (dataSnapshot.exists()) {
\\Fetch the messages...
} else {
Log.d("mymessages", "fetchChatMessages(), dataSnapshot does not exists.");
}
}
@Override
public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
}
@Override
public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
在发送消息的按钮内运行的整个代码
String editTextMessage = messageBodyEditText.getText().toString();
if (!editTextMessage.isEmpty()) {
if (!chatExists) {
final DatabaseReference chat = dbReference.child("chat");
final DatabaseReference user = dbReference.child("user");
chatId = chat.push().getKey();
HashMap newChatMap = new HashMap();
newChatMap.put("id", chatId);
newChatMap.put("users/" + currentUserId, true);
newChatMap.put("users/" + userId, true);
// Creating chats table
chat.child(chatId)
.child("info")
.updateChildren(newChatMap);
//Inserting the contact's id in the current user's chat table
HashMap newUserChatMap = new HashMap();
newUserChatMap.put(chatId + "/contact", userId);
user.child(currentUserId)
.child("chat")
.updateChildren(newUserChatMap);
//Inserting the current user's id in the contact's chat table
HashMap newContactChatMap = new HashMap();
newContactChatMap.put(chatId + "/contact", currentUserId);
user.child(userId)
.child("chat")
.updateChildren(newContactChatMap);
chatExists = true;
newChatCreated = true;
}
if (chatId != null) {
DatabaseReference newMessageDb = dbReference.child("chat").child(chatId).push();
Map newMessageMap = new HashMap<>();
newMessageMap.put("text", editTextMessage);
newMessageMap.put("creator", currentUserId);
newMessageDb.updateChildren(newMessageMap);
messageBodyEditText.setText("");
if (messageList.isEmpty()) {
if (chatExists) {
if (ConnectivityHelper.isConnectedToNetwork(this)) {
dbReference.child("chat").child(chatId).addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
loadingMessages.setVisibility(View.VISIBLE);
loadingWarning.setVisibility(View.VISIBLE);
loadingWarning.setText("Loading messages...");
if (dataSnapshot.exists() && !dataSnapshot.getKey().equals("info")) {
loadingWarning.setText("Loading messages...");
String text = "";
String creatorId = "";
Object newText = dataSnapshot.child("text").getValue();
Object newCreatorId = dataSnapshot.child("creator").getValue();
if (newText != null) {
text = newText.toString();
}
if (newCreatorId != null) {
creatorId = newCreatorId.toString();
}
String creatorName = "";
if (!creatorId.equals(currentUserId))
creatorName = userName;
else
creatorName = creatorId;
Message message = new Message(dataSnapshot.getKey(), creatorName, text);
messageList.add(message);
messagesAdapter.notifyDataSetChanged();
recyclerView.smoothScrollToPosition(messagesAdapter.getItemCount() - 1);
loadingMessages.setVisibility(View.INVISIBLE);
loadingWarning.setVisibility(View.INVISIBLE);
sendButton.setVisibility(View.VISIBLE);
} else {
loadingMessages.setVisibility(View.INVISIBLE);
loadingWarning.setText("Messages not found. \nCould not load your messages :/");
}
}
@Override
public void onChildChanged(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
if (dataSnapshot.exists())
}
@Override
public void onChildRemoved(@NonNull DataSnapshot dataSnapshot) {
}
@Override
public void onChildMoved(@NonNull DataSnapshot dataSnapshot, @Nullable String s) {
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
loadingMessages.setVisibility(View.INVISIBLE);
loadingWarning.setText("Loading cancelled. \nCould not load your messages :/");
Log.d("mymessages", "fetchChatMessages(), onCancelled called.");
}
});
} else {
lyNoConnection.setVisibility(View.VISIBLE);
Log.d("mymessages", "Not connected to network.");
}
} else {
loadingMessages.setVisibility(View.INVISIBLE);
loadingWarning.setVisibility(View.INVISIBLE);
sendButton.setVisibility(View.VISIBLE);
}
}
} else {
Log.d("mymessages", "chatId = null");
}
}