Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 查询firebase数据库时如何将项附加到OnDataChange内部的ArrayList_Java_Android_Firebase_Firebase Realtime Database - Fatal编程技术网

Java 查询firebase数据库时如何将项附加到OnDataChange内部的ArrayList

Java 查询firebase数据库时如何将项附加到OnDataChange内部的ArrayList,java,android,firebase,firebase-realtime-database,Java,Android,Firebase,Firebase Realtime Database,我正在使用firebase,并尝试使用firebase函数正确查询数据。我一直在使用的一种查询数据库许多不同部分数据的解决方案(我非常反对,也非常不确定)就是在整个数据库中添加一个单值事件的侦听器,如下所示: DatabaseReference myRef = FirebaseDatabase.getInstance().getReference(); myRef.addListenerForSingleValueEvent(...)). 我想做的是对我正在侦听的数据库部分使用适当的查询,并记

我正在使用firebase,并尝试使用firebase函数正确查询数据。我一直在使用的一种查询数据库许多不同部分数据的解决方案(我非常反对,也非常不确定)就是在整个数据库中添加一个单值事件的侦听器,如下所示:

DatabaseReference myRef = FirebaseDatabase.getInstance().getReference();
myRef.addListenerForSingleValueEvent(...)).
我想做的是对我正在侦听的数据库部分使用适当的查询,并记住那些值事件侦听器函数之外的数据,如下所示:

Query lastMessageQuery = myRef.child("chat_messages").child(currChatID).orderByKey().limitToLast(1);
lastMessageQuery.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot lastMessageSnapshot) {
        for(DataSnapshot currMessageSnapshot: lastMessageSnapshot.getChildren()) {
            Message lastMessage = currMessageSnapshot.getValue(Message.class);

            if (lastMessage != null) {
                MessageViewBox currMessageView;
                if (isGroup) {
                    currMessageView = new MessageViewBox(
                            lastMessage.getMessage_text(), chatName, chatIcon, lastMessage.getTime_sent(), currChatID, true
                    );
                } else {
                    currMessageView = new MessageViewBox(
                            lastMessage.getMessage_text(), chatName, chatIcon, lastMessage.getTime_sent(), otherUserID, false
                    );
                }
                messageFields.add(currMessageView);
            }
        }
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {

    }
});

Collections.sort(messageFields);
L_MessageListingAdapter messagesAdapter = new L_MessageListingAdapter(
        mView.getContext(), R.layout.a_person_item, messageFields);
mListView.setAdapter(messagesAdapter);
我遇到的问题是,当我想用我的messageFields ArrayList填充listview时,列表已经忘记了它的所有元素

到目前为止,我知道四种可行的解决方案

  • 我可以执行我最初描述的操作,向整个数据库添加一个值事件侦听器,转到包含当前聊天的所有消息的快照,然后迭代到最后。显然,这是不可取的,而且规模会非常大

  • 我可以将每个聊天的最后一条消息id保存在数据库的一个单独部分中,使用监听整个数据库的方法,然后只需要迭代一个值来获取每个聊天的最后一条消息信息。但是,我也不认为这是必要的,因为我上面概述的查询函数工作得非常好

  • 我可以打电话:

    Collections.sort(messageFields);
    L_MessageListingAdapter messagesAdapter = new L_MessageListingAdapter(
        mView.getContext(), R.layout.a_person_item, messageFields);
        mListView.setAdapter(messagesAdapter);
    
    在将项目添加到ArryList后,在查询函数内部,但这会对每个聊天重复这段代码,它会重新加载列表,以供我进行的聊天次数相同,这也是不可取的,这种方法的最大问题是它没有解决我遇到的更大问题,这不仅是这个特殊情况的问题,也是我遇到的许多情况的问题

  • [DESIRED]这就引出了我需要解决的最符合逻辑的问题,即在查询函数之外保持查询数据的活动性

  • 我几乎肯定(4)是可能的,这似乎是最佳实践,但我只是不确定如何以优雅的方式实现这一点。我尝试将ArrayList设置为private、private static、public和public static。所有这些都不起作用


    希望问题是清楚的,我感谢任何能解决这个问题的建议。

    您不能将
    Message
    类的那些对象添加到
    messageFields
    方法中的
    列表
    onDataChange()
    方法之外,并看到在该方法之外填充的相同列表。由于
    onDataChange()
    方法的异步行为,列表将始终为空。这意味着,甚至在从数据库获取数据之前,也会调用此方法。因此,一个快速解决方法是在方法中使用该列表,或者通过读取我的答案的最后一部分来尝试处理该异步方法。

    我开始意识到这确实是个问题,数据实际上并没有被遗忘,而是在数据被提取之前创建了我的列表。我已经看过您的解决方案,需要对代码进行一些重构才能产生预期的结果,但一般来说,向整个数据库添加一个侦听器是一种非常糟糕的做法吗?或者根据您在该事件侦听器中所做的操作是否可以?您可以根据需要在项目中添加任意多的侦听器,但只需一个条件,即可根据活动的生命周期相应地删除它们。只需将侦听器添加到要侦听的节点。它是bd来监听整个数据库的,这样会浪费资源和带宽。说明了在何处添加/删除侦听器。好的,感谢您的说明和指示,非常感谢。