Building a messenger app from scratch is one of the best learning experiences for any developer. Here's how I architected SayHi — a full-featured Android messenger clone.
Features Implemented
- 💬 One-on-one messaging
- 👥 Group chats
- 📸 Image sharing
- ✅ Read receipts
- 🟢 Online/offline status
- 🔔 Push notifications
- 🔍 User search
- 👤 Profile management
Architecture Decisions
Real-Time Data: Firebase Realtime Database
I chose Firebase over WebSockets for simplicity. Firebase handles:
- Real-time message delivery
- Offline data persistence
- Automatic reconnection
- Conflict resolution
For a production app with millions of users, you'd want a custom backend. But for learning and small-medium apps, Firebase is perfect.
Data Model
The trickiest part was modeling conversations efficiently:
users/
{userId}/
name, avatar, status, lastSeen
conversations/
{conversationId}/
participants, lastMessage, timestamp
messages/
{conversationId}/
{messageId}/
sender, text, timestamp, readBy
This structure allows efficient queries for both conversation lists and message histories.
Handling Edge Cases
Real messaging apps have subtle complexity:
- Message ordering — timestamps can differ between devices
- Read receipts — tracking who read what, when
- Typing indicators — debouncing to avoid spam
- Image messages — compression, upload progress, thumbnails
- Offline queuing — messages sent while offline
Push Notifications
Firebase Cloud Messaging handles push notifications. The tricky part is knowing WHEN to send them — only when the recipient isn't actively viewing the conversation.
What I'd Do Differently
- Use Kotlin instead of Java (cleaner code)
- Implement end-to-end encryption from the start
- Add voice messages
- Use a proper image loading library
The Source Code
The entire app is open source: ⭐ github.com/p32929/SayHi
Study it, fork it, or use it as a reference for your own chat app. The architecture patterns apply to any real-time application.
Top comments (0)