Firebase返回意外值

时间:2018-02-21 15:45:09

标签: java android firebase firebase-realtime-database

在下文中,我将尝试解释在使用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

1 个答案:

答案 0 :(得分:0)

  

问题:虽然这是按预期工作的,但我注意到一些功能无效,特别是在应用程序的首次启动时,在线状态完全随机显示。为了解决这个问题,需要离开聊天活动,返回主菜单并重新进入聊天室。之后一切都正确显示

我认为在你的`主菜单中有在线或聊天室的代码更新状态,所以你需要在恢复申请时再次更新状态