在下文中,我将尝试解释在使用AS从Firebase数据库检索数据时遇到的问题。
应用程序的结构:目前包括两个活动,主菜单和聊天。活动聊天显示消息,用户名和图标(用户类型,即管理员和在线状态)
为了在聊天室中获取在线状态,对于每条消息,用户名存储在ArrayList中并传递给第二个数据库参考(第一个参考用于消息),它迭代所有名称并检索时间戳相应
问题:虽然这是按预期工作的,但我注意到某些功能无效,特别是在应用程序首次启动时,当显示在线状态时完全随机。为了解决这个问题,需要离开聊天活动,返回主菜单并重新进入聊天室。之后一切都正确显示。
我注意到消息和用户名的输出完全符合预期,时间戳虽然是随机的,但导致在线状态显示为所有消息的在线状态或前半部分离线,后半部分在线。
下面,我将包括代码段和屏幕截图。如果您有关于如何改进我的代码或任何有用链接的建议,请告诉我,我还是初学者:)
public void chatLinstenerFirebase() {
chatMessageCap();
playerNames.clear();
playerOnlineResult.clear();
// Path holding the current administration information in the Database
mDatabase = FirebaseDatabase.getInstance().getReference("/chat/messages");
mDatabase.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
execChat.loadUrl("https://*****/exec32014472?uid=" + UUID);
String value = dataSnapshot.getValue(String.class);
String key = dataSnapshot.getKey();
// Example for keyParts[] = 1519214361812@user@player
String keyParts[] = key.split("@");
ArrayList<String> nameParts = new ArrayList<>();
// Storing username
nameParts.add(keyParts[2]);
for(String res : nameParts) {
res = keyParts[2];
// Storing username for second database Reference
playerNames.add(res);
}
// Storing player type i.e user/mod/admin
String playerType = keyParts[1];
if(playerType.equals("dev")) {
playerTypeIcon.add(R.drawable.devicon);
}
if(playerType.equals("user")) {
playerTypeIcon.add(0);
}
if(playerType.equals("mod")) {
playerTypeIcon.add(R.drawable.modicon);
}
if(playerType.equals("admin")) {
playerTypeIcon.add(R.drawable.adminicon);
}
// Displaying time when message was sent
long timestamp = Long.parseLong(keyParts[0]);
Date localTime = new Date(timestamp);
String format = "HH:mm";
SimpleDateFormat sdf = new SimpleDateFormat(format);
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
String formattedDate = sdf.format(localTime);
timestampResult.add(formattedDate);
messageResult.add(value);
// Getting player timestamps to append online/offline icon
if (playerNames.size() >= message_count) {
// Iterate through all players in the chat-room
for (String n : playerNames) {
bDatabase = FirebaseDatabase.getInstance().getReference("/lastonline/" + n);
bDatabase.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
timestampOfPlayer = (long) dataSnapshot.getValue();
long currentTimeStamp = System.currentTimeMillis();
if (timestampOfPlayer + 300000 >= currentTimeStamp) {
playerOnlineResult.add(R.drawable.playeronline);
}
if (timestampOfPlayer + 300000 < currentTimeStamp) {
playerOnlineResult.add(R.drawable.playeroffline);
}
if (playerOnlineResult.size() >= message_count) {
result();
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
}
...
...
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
playerNames.remove(0);
messageResult.remove(0);
timestampResult.remove(0);
playerTypeIcon.remove(0);
playerOnlineResult.remove(0);
}
...
...
});
}
public void result(){
adapter = new ChatAdapter(this, playerNames, messageResult, timestampResult, playerTypeIcon, playerOnlineResult);
messagecontainer.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
Screenshot: left side shows wrong online status on first launch, right side works as expected
答案 0 :(得分:0)
问题:虽然这是按预期工作的,但我注意到一些功能无效,特别是在应用程序的首次启动时,在线状态完全随机显示。为了解决这个问题,需要离开聊天活动,返回主菜单并重新进入聊天室。之后一切都正确显示
我认为在你的`主菜单中有在线或聊天室的代码更新状态,所以你需要在恢复申请时再次更新状态