Home > Software design >  Messages are showing randomly in my chat app not in sequence in firebase android
Messages are showing randomly in my chat app not in sequence in firebase android

Time:10-31

I have built a chat app in firebase android everything is working fine the only problem is that when users are chatting with each other the messages are not showing in order or sequence they are just showing randomly. Image should be shown in proper sequence but it is not working please check it guide me why this is happning? thank you in adnvace

image here

enter image description here I have no idea why is this happening

this is Adapter

public class MessageAdapter extends RecyclerView.Adapter {

Context context;
ArrayList<Message> messageArrayList;

int ITEM_SENT = 1;
int ITEM_RECEIVE = 2;

String senderRoom;
String receiverRoom;

public MessageAdapter()
{

}

public MessageAdapter(Context context, ArrayList<Message> messageArrayList, String senderRoom, String receiverRoom) {
    this.context = context;
    this.messageArrayList = messageArrayList;
    this.senderRoom = senderRoom;
    this.receiverRoom = receiverRoom;
}

@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

    if (viewType==ITEM_SENT)
    {
        View view = LayoutInflater.from(context).inflate(R.layout.senderchatlayout, parent, false);
        return new SenderViewHolder(view);
    }else
    {

        View view = LayoutInflater.from(context).inflate(R.layout.receiverchatlayout, parent, false);
        return new RecieverViewHolder(view);
    }
}

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {

    Message message = messageArrayList.get(position);
    if (holder.getClass() == SenderViewHolder.class)
    {

        SenderViewHolder viewHolder = (SenderViewHolder) holder;
        viewHolder.textViewMessage.setText(message.getMessage());
        viewHolder.timeofmessage.setText(message.getCurrenttime());
    }else
    {
        RecieverViewHolder viewHolder = (RecieverViewHolder) holder;
        viewHolder.textViewMessage.setText(message.getMessage());
        viewHolder.timeofmessage.setText(message.getCurrenttime());
    }

}

@Override
public int getItemViewType(int position) {

    Message message = messageArrayList.get(position);
    if (FirebaseAuth.getInstance().getCurrentUser().getUid().equals(message.getSenderId()))
    {
        return ITEM_SENT;
    }else
    {
        return ITEM_RECEIVE;
    }

}

@Override
public int getItemCount() {
    return messageArrayList.size();
}

  public class SenderViewHolder extends RecyclerView.ViewHolder
  {

   TextView textViewMessage;
   TextView timeofmessage;

   public SenderViewHolder(@NonNull View itemView) {
       super(itemView);

       textViewMessage = itemView.findViewById(R.id.senderMessage);
       timeofmessage = itemView.findViewById(R.id.senderTime);
   }
 }

public class RecieverViewHolder extends RecyclerView.ViewHolder
{

    TextView textViewMessage;
    TextView timeofmessage;
    public RecieverViewHolder(@NonNull View itemView) {
        super(itemView);

        textViewMessage = itemView.findViewById(R.id.receiverMessage);
        timeofmessage = itemView.findViewById(R.id.receiverTime);
    }
}

}

CODE TO GET MESSAGES IN ChatActivity

public class SpecificChatActivity extends AppCompatActivity {

ActivitySpecificChatBinding binding;
private FirebaseAuth auth;
FirebaseFirestore firebaseFirestore;
private String enteredMessage;
String mreceiveruid, msenderuid;
String senderroom, receiverroom;
String currenttime;
Calendar calendar;
String conversionId;
ArrayList<Message> messageArrayList;
MessageAdapter adapter;
SimpleDateFormat simpleDateFormat;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    binding = ActivitySpecificChatBinding.inflate(getLayoutInflater());
    setContentView(binding.getRoot());

    auth = FirebaseAuth.getInstance();
    firebaseFirestore = FirebaseFirestore.getInstance();
    calendar = Calendar.getInstance();
    simpleDateFormat = new SimpleDateFormat("hh:mm a");
    setSupportActionBar(binding.specificToolbar);

    messageArrayList = new ArrayList<>();

    String id = UUID.randomUUID().toString();

    Intent intent = getIntent();
    String name = intent.getStringExtra("name");
    String image = intent.getStringExtra("profileImage");

    msenderuid = auth.getUid();
    mreceiveruid = intent.getStringExtra("receiverUid");

    senderroom = msenderuid mreceiveruid;
    receiverroom = mreceiveruid msenderuid;


    binding.specificUserName.setText(name);
    if (!image.isEmpty())
    {
        Glide.with(getApplicationContext())
                .load(image)
                .placeholder(R.drawable.userchaticon)
                .into(binding.specificUserImage);

    }


    binding.sendBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            enteredMessage = binding.messageBox.getText().toString();
            if (enteredMessage.isEmpty())
            {
                Toast.makeText(SpecificChatActivity.this, "Entered some message", Toast.LENGTH_SHORT).show();
            }else
            {

                Date date = new Date();
                currenttime = simpleDateFormat.format(calendar.getTime());
                Message message = new Message(enteredMessage, auth.getUid(), mreceiveruid,  date.getTime(), currenttime, name, image);
                firebaseFirestore.collection("Chats")
                        .document(senderroom)
                        .collection("Messages")
                        .document()
                        .set(message).addOnCompleteListener(new OnCompleteListener<Void>() {
                    @Override
                    public void onComplete(@NonNull Task<Void> task) {


                        firebaseFirestore.collection("Chats")
                                .document(receiverroom)
                                .collection("Messages")
                                .document()
                                .set(message).addOnCompleteListener(new OnCompleteListener<Void>() {
                            @Override
                            public void onComplete(@NonNull Task<Void> task) {

                            }
                        });
                    }
                });

                binding.messageBox.setText(null);

            }

        }
    });

    LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
    linearLayoutManager.setStackFromEnd(true);
    binding.specificUserRecycler.setLayoutManager(linearLayoutManager);
    adapter = new MessageAdapter(SpecificChatActivity.this, messageArrayList, senderroom, receiverroom);
    binding.specificUserRecycler.setAdapter(adapter);

    CollectionReference collectionReference = firebaseFirestore.collection("Chats").document(senderroom)
            .collection("Messages");
    collectionReference.addSnapshotListener(new EventListener<QuerySnapshot>() {
        @Override
        public void onEvent(@Nullable QuerySnapshot value, @Nullable FirebaseFirestoreException error) {
            messageArrayList.clear();

            for (DocumentSnapshot snapshots : value.getDocuments())
            {
                Message message = snapshots.toObject(Message.class);
                messageArrayList.add(message);
            }
            adapter.notifyDataSetChanged();
        }
    });
    
}
}

CodePudding user response:

documents in Firebase Firestore are not stored in the order of there creation time, they are ordered by there id name. which in your case is a random ID generated by Firebase itself.

You have two options, the first one is to generate the documents IDs by yourself, by tracking the last ID number in that collection and incrementing it (1, 2, 3...etc), the second option (which I would recommend) is to combine your date and time fields into one fields by simply adding the timestamp values and call it something like dateTime for example, and then using the orderby('dateTime') method that Firebase provide while querying from the collection, for more info on how to use it check out the documentation here

CodePudding user response:

On getting collection reference it is possible to apply orderBy method and then add a snapshot listener. Probably, Firebase stores the entities in different order rather than you expect and order by creation date should be declared explicitly.

firebaseFirestore.collection("Chats").document(senderroom)
        .collection("Messages")
        .orderBy("${dateField}")
        .addSnapshotListener(...)
  • Related