Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly handle 'read' - 'unread' state for a chat messaging app?

I'm currently working on a react-native application that provides a chatroom features using socket.io

I'm currently willing to deal with unread/read state on messages but I do not know where this logic shall lives : in the client side code or in the server side ?

Here is a basic implementation in termes of components of my code

<ChatRoomCard /> //-> displays the last message and the chatroom title and 
                    can navigate to the ChatRoom component
<ChatRoom id={} />

My reduxState is like so :

{
  chatRooms: [{chatRoomId: '', title: ''}],
  chatRoomsMessages: {
           [chatRoomId]: [{messageId: '', text: ''}]
     }
}

Each component is connected to redux and the ChatRoomCard receives the chatRooms props containing an array of objects `[{chatroomId: ''}] whereas the ChatRoom component receives only the according messages.

If it is on the client side my first attempt will be to add a state lastRead : timestamp to each ChatRoomCard, this state will be updated each time the ChatRoom component mounts thus displaying the last messages.

So now when the socket io event 'new msg' triggers and I receives the new message I can, in the ChatRoomCard component, map the messages comparing the message.createdAt timestamp with the ChatRoomCard.lastReadTimestamp and increment a 'unread messages count' whenever a message.timestamp is after the lastReadTimestamp.

Does this solution sounds like good work ? Or is this logic belongs to the back-end ? Or maybe is it both ? I'm a little bit lost since it is the first time that I'm doing this

Thanks a lot

like image 844
MaieonBrix Avatar asked Dec 06 '17 10:12

MaieonBrix


2 Answers

Such decisions involve a trade-off between different goals, each solution has advantages and disadvantages:

  • If you do it in front-end you use less power in server, so is scaling out more easly.
  • If is not some complex calculation and you do it in the front-end, user experience is improved, because there is not network latency.
  • For security reasons and if the information has some degree of sensitive data is better to do any state-changes in server because client maybe is under of attack of some hacker.
  • If the information will be used again from many users or sessions best solution is to store it in database, so the calculation will go to the server and saved to the database.
  • If backend is stateless maybe is need to re-retrive the data from the database. Frontend maybe has this data ready for use, from previous requests.

More specific to your problem now:

We want to add an information in a component, so for sure the data must reach the component. Someone must calculate this information. The component has the responsibility only about the presentation and what to give to the user, no how the data calculate. So the component will not do the calculation.

State, the next link in the chain, has the information that is needed to calculate this information and give it to the component. I think this is the best solution cause your data is not sensitive or must saved to the database.

The best way to do this, is be using react-redux.connect with a function like the mapStateToProps. A full example and explanation is here.

like image 103
Thomas Karachristos Avatar answered Sep 29 '22 19:09

Thomas Karachristos


A message component can have a boolean read: false; where this also exists in the state as well as in the server recording this new information.

When the user opens this new message; i.e., when the message lands as a component, the life-cycle method ComponentDidMount() can be overwritten to change this boolean to read: true.

This can be done through the appropriate redux way of new actions, reducer logic and component render modifications that implement your read gui indication to the user.

That's my jab at this, I'm just starting out myyself, could be wrong but I'll try implement some code myself and update this answer after I confirm.

like image 45
Mo Moalin Avatar answered Sep 29 '22 18:09

Mo Moalin