BUG: unread_messages return incorrect in read state
In read state, last_read_message_id is always true (with the actual id I marked via API channel.markRead({ message_id: messageId })) But sometimes, unread_messages return incorrect, always = 0
Some specific cases:
- actual unread_messages > 99: I have 120 unread messages, then I go to the detail screen, the my code will call markRead with the id of the next 15th message (every time I go in details, the default is to call and mark 15 messages as read). When I go back to the list screen, unread_messages should be = 105, but it returns = 0. This error can always be reproduced, please see the video below
- when the last message is a system message
- in some cases, for reasons I don't know, when I actually have 50-60 unread messages, it also returns = 0.
I am using: "stream-chat": "8.14.4", but when I updated to "8.33.1", this bug is still
https://github.com/user-attachments/assets/6186146c-938a-4479-be80-e1a561891a17
Hey @thaindangelhack , could please share how your channel.markRead call looks like? What params are you passing to the method? Are you using only stream-chat-js or also React or RN SDK? If you use one of those, do you use markRead function provided over the context?
@MartinCupela Thanks for the quick response.
I'm using: "stream-chat": "8.14.4" "getstream": "8.0.1"
Hey @thaindangelhack , the channel.markRead() method does not support passing message id. You can mark only whole channel as read.
@MartinCupela So why when I call API with that param, response is still returned success and last_read_message_id is still updated with the correct value passed in param? Is there any way to mark messages as read by ID?
We want to display the number of unread messages in real time as the user scrolls through the message and code will marks it as read.
Hey @thaindangelhack , the
channel.markRead()method does not support passing message id. You can mark only whole channel as read.
@MartinCupela I checked again and it's true as you said, this method is not supported, but somehow the previous dev still passed the param and used it. But I don't think it's the reason why unread_messages is returning wrong (= 0) Because the value of last_read_message_id is not compatible with unread_messages => I think this is a library data storage issue that needs to be fixed
From the library docs i have another way to implement my need: always call mark the whole channel as read then use the sent messageId and mark as unread. It works now but there is a limitation from the library: "For performance reasons it's only possible to mark any of the last 100 messages of the channel as unread." => I can't keep my unread message count above 100. But this seems to be a good temporary solution with what the library supports
Hope you have a better solution can suggest me. Thanks!!!
Hello @thaindangelhack
- Regarding this:
But I don't think it's the reason why unread_messages is returning wrong (= 0)
You state this:
the my code will call markRead with the id of the next 15th message (every time I go in details, the default is to call and mark 15 messages as read). When I go back to the list screen, unread_messages should be = 105, but it returns = 0.
If summarized the above statement: 1. call markRead 2. unread_messages === 0. That is expected behavior - marking a channel read, you get 0 unread messages. Could you please explain why do you consider it incorrect?
- Please explain
last_read_message_id is not compatible with unread_messages
How it is not compatible?
-
Limit of 100 messages marked unread This is a back-end limitation that the SDK cannot circumvent.
-
Marking the channel read and then marking the 100th message unread You can arrive to a situation when you send a markUnread request with idX, but in the meantime a new message arrives to the back-end and you will end up with error. Also you may reach the API endpoint limit and suddenly will not be able to mark unread. You can easily reach the limit if you want to mark unread on scroll event. I can imagine the UX will be quite bad.
I would recommend not to fixate on functionality that simulates marking individual messages unread.
hi @MartinCupela
1 & 2: After call markRead and get value unread_messages === 0, equivalent to the messages in the channel have been read by that user, as I understand, now last_read_message_id must match the id of the last message in the channel, is that correct? But in fact in some cases as I said at the beginning it does not match, that is the incompatibility I want to talk about See example at 2m30s in above video
3: ok
4: I have anticipated this So if markUnread returns an error exceeding the limit I will continue to handle it as follows: query the channel to get the 99th message and call the function to retry markUnread, this is to ensure the user can still know that they have many unread messages (>99) If this time it still cannot mark unread, then we accept marking the whole channel as read, as you said, maybe at that time there were new messages sent causing the number to exceed, but at this time the user is in the chat channel (details screen), marking the whole channel as read is what I think is appropriate
5:
I would recommend not to fixate on functionality that simulates marking individual messages unread.
This is a feature we want, so I'm trying to make it as good as possible Do you think the above solution is ok?
hey @thaindangelhack,
1&2 The situation when the last_read_message_id is not the last message is when the last message has been soft / hard deleted. The JS client just mirror the server state.
4: I still think this is a fragile solution. Also large amounts of requests to the infrastructure can have impact.
I would not recommend what you proposed.
@MartinCupela
last_read_message_id is the last message that user read, right? i got it here
I mean, if unread_count = 0 then last_read_message_id of that user must equal id of last message in channel (channel now has no new messages while calling API to get data) But that is not correct in the data i get as i mentioned in the video
If the last message is deleted, then the last message id is not equal to the last message, but the previous message that is not deleted. Deleted messages are not included in the unread count.
what do you mean deleted message? my channel is currently full of intact messages, no deletions or edits. we don't even have a delete message feature in our app
@MartinCupela I m having the same issue I can't get the read count always returning 0
I identified the issue by using the same code but changing the API key to one from a newly created GetStream account, which correctly displays the number of unread messages. From this perspective, it appears that GetStream somehow suddenly marked all messages as read for the previous account
@fawzii0x3 Can you share more details about the API key you found the issue with? Do you have any solution for it?
@thaindangelhack check channels type config my issue was related to the configuration I change it to default config and it's working now

