简体   繁体   中英

How to sort an ArrayList in onComplete method, firebase

I'm developing and application messages and I want to get the ArrayList sorted of that messages inside onComplete method:

first I go to the collection "messages" to return all the fields of that collection and then I order it by timestamp, and it works fine, it return the query sort it by timestamp

ArrayList<String> getMessages = new ArrayList<>();

I got users collection that I need to use for get the properties of that user who is sending the message, but I need to use it inside the for loop

firebaseFirestore.collection(threads).orderBy(timestamp).addSnapshotListener(new EventListener<QuerySnapshot>() {
    @Override
    public void onEvent(@Nullable QuerySnapshot value, @Nullable FirebaseFirestoreException error) {
        for(QueryDocumentSnapshot document : value){        
            firebaseFirestore.collection("users").document(document.getString("senderId")).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
                @Override
                public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                    getMessages.add(document.getString("message");

                    getTimestamp.add(date);
                    getUserInfo.add(user.getString("firstName"));
                  
                    if (completeCount++ == value.size()-1) {
                        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
                        adapter = new AdapterRecyclerViewThreads(getActivity(), titleThreads, ThreadsId,
                                getUserInfo, getUserImage, getTimestamp, getAnswer);
                        recyclerView.setAdapter(adapter);
                    }
                }
            });
        }
    }
});

outside onComplete method in for loop the array returns (I want to get this):

  • message 1
  • message 2
  • message 3
  • message 4....

inside onComplete method in for loop array returns:

  • message 4
  • message 3
  • message 1
  • message 2

as I said the orderBy works fine, but the problem is when I get the datas inside onComplete method.

I know that this is normal to happen because firebase takes time to process the query, but I need to use the collections "users" inside the for loop to return the data of the users.

I don't think there's a way to guarantee the order in which the load operations complete on Firestore. The easiest way I can think of to keep them in sync is by adding the message to the array in the outer loop, and then updating it in-place with the user info in the inner loop.

So, create a class to hold the MessageAndUserInfo and then:

ArrayList<MessageAndUserInfo> messageAndUserInfos = new ArrayList<>();
...
firebaseFirestore.collection(threads).orderBy(timestamp).addSnapshotListener(new EventListener<QuerySnapshot>() {
    @Override
    public void onEvent(@Nullable QuerySnapshot value, @Nullable FirebaseFirestoreException error) {
        for(QueryDocumentSnapshot document : value){        
            MessageAndUserInfo msg = new MessageAndUserInfo(document.getString("message"));
            messageAndUserInfos.add(msg);
            firebaseFirestore.collection("users").document(document.getString("senderId")).get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
                @Override
                public void onComplete(@NonNull Task<DocumentSnapshot> task) {
                    msg.setUserInfo(user.getString("firstName"));
                    ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM