I was deep into building a real-time chat system for an e-commerce platform.
The goal was simple: enable buyers and sellers to communicate instantly.
I had my stack ready:
- Node.js on the backend
-Socket.IO for real-time events
- MongoDB for persistence
Chat messages were working — messages were being sent, received, and displayed.
But then QA dropped this bomb:
“Messages are going through, but no one knows they have a new one.”
The Problem
The system only sent socket events to users inside the chat room.
If User A sent a message to User B, but B wasn’t in that chat room? No event. No notification. No idea anything happened.
This was a big UX failure.
Debugging & Observations
After logging everything and watching socket joins, I realized:
I only joined users to chat-specific rooms.
I didn’t track users globally (by userId or session).
There was no concept of unread messages.
The Fix
I restructured the socket setup:
// On socket connect
socket.join(token, EuserId);
Then, on message send:
io.to(receiverUserId).emit("newChatNotification", {
message,
from: senderUserId,
});
And for tracking unread messages:
I added an unreadCount field per user-conversation pair in MongoDB.
On message delivery, I incremented it.
When the recipient opened the chat, I reset the count.
Bonus Fixes
Emitted _notificationCountUpdated _events to update badges.
Added fallback logic for users disconnected (queued email/push notifications).
Takeaway
Real-time chat is more than just sending a message.
It’s about:
- User presence awareness
- Smart event routing
- Persisting what matters
- Notifying the right user at the right time
If you're building chat or any real-time feature — plan beyond the message itself.
Don’t just ask: “Did it send?”
Ask: “Will they know it was sent?”
Top comments (0)