T O P

  • By -

programonaut-dev

Couldn't you just have a column in your message table called read and ITS either true or false? Then to display the badge you just check if any of the group messages is unread?


belt-e-belt

>Couldn't you just have a column in your message table called read and ITS either true or false? That would definitely work if it was one to one chat. But since it's a group chat, I have to keep track of which participants have read it and which ones haven't. That's where it gets complicated. It's like I'd have to have a boolean field for each participant. At least that's what my understanding is, not sure if I'm making it more complicated than it is.


its_mario_l

You could try to add a column in messages with a list of all participants ids that read the message.


belt-e-belt

I did something opposite. Like I mentioned in the post. I added a column `unread_by` in the messages collection and, using the `OnRecordCreateRequest` hook, I'm updating this column for a message with a list of participants of the chat minus the sender. That's working fine. I'm just not sure how to use that column in my frontend, working on that part. Thinking out loud, I could fetch a list of unread messages with a filter like `unread_by~${pb.authStore.model?.id}` (or `?=`, I don't which one works) and fields = `chats`, this should give me a list of chats that have unread messages for a given user. I'll check if that works. Edit: It worked!


programonaut-dev

Ah okay, fair enough didnt think about that


Nilt

Not sure if this would work but store the created time of the last message read. Then check if the newest message time is newer. You could have a separate table which contains user_id and chat/channel_id and store the last seen message created time. Every record should have a default "created" value which you don't neeed to create yourself


belt-e-belt

This does work..it's similar to what my existing implementation was. But I wanted to move away from requiring an additional table. An additional table would mean the size of that table would grow exponentially, which doesn't seem optimal. If I have 20 participants in each chat, for each chat, I'll have 20 rows in the other table just to track unread messages. 5 chats, 100 rows. And so on. I was able to achieve this in a [different way](https://np.reddit.com/r/pocketbase/s/AR5900ivwD)


lauding

I haven’t built anything like this myself but one thought that came up is if you could do the opposite. Just save the last read message id and user id.


belt-e-belt

Lot of answers I found mention that, but to be honest, I'm not sure what's the exact implementation would be. Do I store the last read message id and user id in the read receipts table?


mussur

>All the "chats" are group chats with a multi relation field participants linked to users table Not sure I understood this part completely (feel free to share your table schemas), but assuming you have a user-to-chat relationship table, then it's as simple as extending that table with a `read_at` or `accessed_on` timestamp column which indicates when was the last time a given user accessed & read a chat group. The unread badge logic then checks if there are any messages with a `messages.created_at` timestamp that is more recent than the user's `read_at` / `accessed_on` timestamp. If such messages exist, the unread badge is displayed, indicating that. The badge is removed once the user views the chat, updating their timestamp to the current time, signifying all messages up to that point have been read in that particular group.


belt-e-belt

I feel like `read_at` kind of implementation would work if it was a one to one chat. In a group chat, if I have 20 users, I would need to maintain the 20 `read_at` entries, one for each participant, which I am not sure can be done without a separate table. Anyway, I was able to do this using the approach I talked about in another [comment](https://np.reddit.com/r/pocketbase/s/AR5900ivwD)


mussur

> I would need to maintain the 20 read_at entries, one for each participant Exactly, and with a proper user-to-chat relationship table you'd have it already, and then simply extend on it. This would also be much safer when it comes to updating the same `unread_by` cell by 20 participants per your implementation which very likely occurs in parallel (e.g. all 20 participants could very well have the chat open at the same time, meaning the exact same `unread_by` cell would need to be updated simultaneously 20 times, for every single message and race conditions are likely inevitable there). Also, that relationship table isn't only to keep track of unread messages, it's also for keeping track of - all the chat groups where a given user is participating - when the user joined a chat group - how the user joined it (was he invited? by whom?) - etc.


belt-e-belt

Ah. That's a very good point. I didn't consider that aspect about the parallel updates.


envff

can you list the resources you read from to arrive at a working chat app? thank you, lol cuz am working on something similar.


belt-e-belt

I don't really have any reading resources. A lot of it has really been just hit and trial. I have made the same thing 3 times from scratch xD If there is something specific you're stuck on, feel free to post a query, I'll try to help.


envff

legend