I am using firebase, and trying to query data properly using firebase functions. A solution for querying data from many different parts of the database that I've been using, which I am highly against and am really unsure about, is simply adding a listener for single value event to the entire database, like so:
DatabaseReference myRef = FirebaseDatabase.getInstance().getReference();
myRef.addListenerForSingleValueEvent(...)).
What I would like to do is use proper querying for the parts of the database I'm listening in on, and remember data outside of those value event listener functions, like so:
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);
The issue I'm running into is that by the time I want to fill the listview with my messageFields ArrayList, the list has forgotten all of its elements.
As of now, I know of four working solutions.
I can do what I described initially, add a value event listener to my entire database, go to the snapshot containing all messages for a current chat, and then iterate through to the end. Clearly this is undesirable and would scale horribly
I could save the last message id for each chat in a separate part of the database, use the approach of listening in on the entire database, and then only have one value to iterate through to get the last message information for each chat. But again, I don't believe this is necessary because the query function I outlined above works perfectly.
I could call:
Collections.sort(messageFields); L_MessageListingAdapter messagesAdapter = new L_MessageListingAdapter( mView.getContext(), R.layout.a_person_item, messageFields); mListView.setAdapter(messagesAdapter);
inside of the query function after adding the item to the ArryList, BUT this repeats this segment of code for each chat, it reloads the list for as many chats that I have to go through, which again, is undesirable, and the biggest issue I have with this approach is that it doesn't address the larger issue I'm having, which isn't only a problem for this particular situation, but many situations that I'm running into.
[DESIRED] So this brings me to the most logical issue I need to solve, which is the issue of keeping the data queried alive outside of the query function.
I'm almost positive that (4) is possible, and it seems like it would be the best practice, but I'm just unsure of how to do achieve this in an elegant way. I tried making the ArrayList private, private static, public, and public static. None of this is working.
Hopefully the question is clear, and I appreciate any advice that would solve this problem.