Need guidance on how to make my chat functionality, please help!

Hi guys, I'm trying to create a chat app and i've ran into some trouble. When inside a chat, getting new messages into the UI is fine and works great. It's really simple, just listen to the conversationMessages table and filter by the conversationId that we are currently on - Great stuff ✅ The problem I have is the Inbox component. It needs to show: - All current conversations you're involved in - The latest message sent to each chat - Whether it has been read or not by the user (I compare conversationMembers.lastRead with the latest conversationMessages.createdAt - Needs to update in realtime - if im on my inbox screen and get a new message, I expect that chat to move up to 1st place and show the new message. I have created a view called conversationsView that gets all the above data ready for me and it works great. However, I failed to realise you cannot use realtime on views 😔 so my plan has failed on the last hurdle. When a new message is sent, the inbox is not updated in realtime. Does anyone see a way of achieving this? Im quite new to SQL. I've attached an image of my db design and chat component. I've spent 3 days trying to figure out a way of doing this 😆 If anyone has a good method of achieving this please put me out of my misery haha.
No description
14 Replies
lewisd
lewisdOP3y ago
Example of the problem:
No description
lewisd
lewisdOP3y ago
One method I have in my head is: I could maybe fetch a batch of 10 conversations in the inbox component, create an array of id's from the conversations and use the realtime filter conversationId=in.(${idBatch}) on the conversationMessages table. When a new message is inserted into any of conversations in the batch, update the inbox component on the left. I'll then repeat this for the amount of batches of conversations the user has and paginate them, bringing in another 10 when they scroll to the bottom. Any opinions on this?
garyaustin
garyaustin3y ago
There is no in filter in realtime currently.
lewisd
lewisdOP3y ago
Thanks @garyaustin, that's the second plan out the window haha. Saved me a lot of time there, was going to give that a go tonight Bump, anyone got any ideas? 🥲 Is this one of the times a noSQL db is required?
jdgamble555
jdgamble5553y ago
Didn't you say you were able to add other filters by using RLS? Not sure if that is best bet or not without moving to Hasura (Firebase can't handle relations)
thestepafter
thestepafter3y ago
@lewisd use something like Pusher since realtime doesn't work on views. Or you could do realtime on a table instead of a view and use triggers to populate it.
silentworks
silentworks3y ago
Create a separate table that updates each time you update the conversationMessage table, the table should contain the conversationId, lastMessage and userId. This way you can do realtime on this table for the inbox component.
jdgamble555
jdgamble5553y ago
Didn't someone say there was a way to add filters with RLS?
silentworks
silentworks3y ago
RLS is for restricting access to data not filtering.
jdgamble555
jdgamble5553y ago
right, but I thought @garyaustin said you could use RLS to hack the filter problem somewhere
garyaustin
garyaustin3y ago
RLS will limit what realtime returns. So only for your chat rooms , your user id, etc. Just like it does for select. If you have RLS on the message table to check and see if you are a member of the room to see the message, then that would apply to realtime also. So you would not want to waste your filter on something already being done by RLS unless you want to filter those messages even more. It is not sufficient to just use a filter on user id or room id's anyway as the client can hack that. I don't know if that is relevant here as I did not look at the ops detail, just their desire to use an in filter.
lewisd
lewisdOP3y ago
That makes sense, so basically what im doing in a view but use an actual table. Sorry for bugging you with one last question: If it updates on every message sent, would you either: 1. Create a db trigger to do the updating 2. When the user taps Enter, send two requests at the same time, the usual message creation + update this new conversation table
garyaustin
garyaustin3y ago
Use a trigger you don't have to worry about 1 failing (both will fail if either does) and faster.
lewisd
lewisdOP3y ago
Awesome cheers guys, ill get to work tonight!

Did you find this page helpful?