0

I'm working on a chat app where user can see last message of conversation. But I am stuck with this situation where i am unable to get last message.

I have tried this query like

DatabaseReference getLastMessageRef = 
FirebaseDatabase.getInstance().getReference("FriendsMessages");
Query query1 = getLastMessageRef.child(common.currentUser.getPhone()).child(id).orderByKey().limitToLast(1);

Where common.currentUser.getPhone is number/id of current user and id is id of other person.

And database structure is like DATABASE STRUCTURE PICTURE

private void getAllMessages() {

    Query query = FirebaseDatabase.getInstance().getReference("FriendsMessages").child(common.currentUser.getPhone());
    FirebaseRecyclerOptions<MessageModel> options = new FirebaseRecyclerOptions.Builder<MessageModel>()
            .setQuery(query,MessageModel.class)
            .build();


    adapter = new FirebaseRecyclerAdapter<MessageModel, ShowAllMessageViewHolder>(options) {
        @Override
        protected void onBindViewHolder(@NonNull final ShowAllMessageViewHolder holder, int position, @NonNull final MessageModel model) {


            String id = adapter.getRef(position).getKey();

            DatabaseReference getFriendDataRef = FirebaseDatabase.getInstance().getReference("User");
            DatabaseReference getLastMessageRef = FirebaseDatabase.getInstance().getReference("FriendsMessages");


            getFriendDataRef.child(id).addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {

                    if (dataSnapshot.exists()){

                        String dp = dataSnapshot.child("img").getValue().toString();
                        String name = dataSnapshot.child("name").getValue().toString();

                        holder.MessageName.setText(name);
                        Picasso.with(getBaseContext()).load(dp).into(holder.messageDp);

                    }

                }

                @Override
                public void onCancelled(DatabaseError databaseError) {

                }
            });


            Query query1 = getLastMessageRef.child(common.currentUser.getPhone()).child(id).orderByKey().limitToLast(1);

            query1.addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {

                    String mesaage = (String) dataSnapshot.child("message").getValue();

                    Toast.makeText(mContext, ""+mesaage, Toast.LENGTH_SHORT).show();
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {

                }
            });


        }

        @NonNull
        @Override
        public ShowAllMessageViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.card_message_view,parent,false);

            return new ShowAllMessageViewHolder(view);
        }
    };
    showAllMessages.setAdapter(adapter);
    adapter.notifyDataSetChanged();
}

I am getting null string.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193

1 Answers1

1

One thing to remember is that Firebase keys are always Strings. And when strings are ordered, are ordered lexicographically.

If you want to get the last element, add to each message object a new property that can hold a timestamp. This is how you can add it to the database and get it back. In the end, simply create a query and order the elements according to this new timestamp property and call limitToLast(1). That's it!

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • Hi Alex thanks for answering but i just wanted ask like my query was right no? – user10072456 Feb 12 '19 at 16:37
  • No, it's not. It will never return the last item according to a time component. It will retrun a last element. You cannot order according those strings and expect to behave as it were timestamps. – Alex Mamo Feb 12 '19 at 16:45
  • i want last element only but it's retrieving it. Giving me null error – user10072456 Feb 12 '19 at 16:47
  • Have you tried to hardcode the values of `common.currentUser.getPhone()` and `id` in your query `Query query1 = getLastMessageRef.child(common.currentUser.getPhone()).child(id).orderByKey().limitToLast(1);`? Does it work that way? – Alex Mamo Feb 12 '19 at 16:49
  • yes i have passed value like Query query1 = getLastMessageRef.child(common.currentUser.getPhone()).child(id).child("Name of node"); and was working – user10072456 Feb 12 '19 at 16:52
  • It means that your values are wrong. Be sure to have the correct values and it will work. – Alex Mamo Feb 12 '19 at 16:53
  • both of them having a stored corrected values. I dont know why its not working with OrderByKey.LimitToLast – user10072456 Feb 12 '19 at 16:54
  • Check the value that you are getting in field "id", if you are getting null then the id value might be incorrect. – ManishPrajapati Feb 13 '19 at 09:01