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):
inside onComplete method in for loop array returns:
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.