Elastic Search - Chat and Messages
Elasticsearch (ES) is used in Hububb Chat to make thread lists fast, searchable, and always up to date. Instead of reading every message from the database each time, we keep a lightweight copy of each thread in Elasticsearch. This allows users to quickly:
Search and filter chats by keywords, tags, or participants
Sort by newest activity, unread status, or importance
Instantly see updated lists without loading full message histories
In short: Firestore stores the full chat data, and Elasticsearch powers fast searching and sorting for the chat inbox.
Why We Use Elasticsearch
Firestore is excellent for reliable storage and live updates — but not for complex queries or sorting large lists (e.g., “show all unread threads sorted by recent activity and tags”).
Elasticsearch solves this by:
Indexing threads with fields optimized for search and filtering
Supporting compound queries (e.g., unread + tagged + support type)
Returning results quickly even when thousands of threads exist
It turns Firestore’s raw data into a read-optimized view of the chat system.
What We Index (and Why)
We do not index every message — only thread-level information.
Each indexed document represents a thread and contains:
id: Thread ID (matches Firestore document)
createdAt / updatedAt: Timestamps for sorting and freshness
participantIds: User IDs participating in the thread
type: ONE_TO_ONE, OPERATIONS_GROUP, or OPERATIONS_ONE_TO_ONE
source: Where the conversation started (hububb, channex, operations, etc.)
externalThreadId / externalSource: For OTA or channel integrations
propertyId: Linked property (if any)
isImportant: Whether the thread is starred or prioritized
needsAttention: List of user IDs who have unread messages
tags: Optional labels for categorization or workflow
guestCoordinationActive: Indicates guest coordination team involvement
lastMessage (snapshot): A lightweight copy of the most recent message (author, body, timestamp)
Note: Elasticsearch only mirrors summary information — full messages are always loaded from Firestore when opening a thread.
How Elasticsearch Fits Into the Chat Flow
1. Thread Creation
When a new thread is created in Firestore, it’s also added to the threads index in Elasticsearch (ELASTIC_THREADS_INDEX).
If ES fails, Firestore remains the source of truth — no user data is lost.
2. New Message
When a message is sent:
Firestore updates the thread (
lastMessage,updatedAt,needsAttention, etc.).The updated thread is immediately re-indexed in Elasticsearch.
The chat list, unread count, and sorting all reflect this change instantly.
If ES fails temporarily, the UI may briefly lag until the next update syncs it.
3. Read / Unread Updates
When a user reads a thread:
Firestore clears them from
needsAttention.Elasticsearch updates the same field (and adjusts sorting if needed).
When a user marks a thread unread:
The user’s ID is re-added to
needsAttentionvia a lightweight ES script update.
4. Tags & Importance
Operations and landlords can tag or star threads:
Firestore updates
tagsorisImportant.Elasticsearch mirrors the update to keep the chat list accurate.
5. WhatsApp / External Events
When WhatsApp or OTA messages arrive:
Firestore updates the thread and creates a message.
Elasticsearch syncs automatically, so unread counts and sorting stay correct.
Reading from Elasticsearch
When you open the chat inbox or the Support Chat:
The system queries Elasticsearch, not Firestore, for speed.
Threads are filtered and sorted based on:
Role and permissions (operations, landlord, etc.)
Support mode or guest-coordinated filters
Tags, importance, and unread status
After results are returned, participant and author info are fetched from the database to enrich the response.
Sorting Modes
Newest
Sorts by updatedAt descending
Unread First
Unread threads (based on needsAttention) appear first, then by recent activity
Important First
Prioritized threads first, then by recent activity
Example Filtering
Landlord View: Only threads where their
uidis inparticipantIds.Operations View: All threads, but filtered by type (support, group, etc.).
Guest Coordinator View: Threads with
guestCoordinationActive = true.
What’s Not in Elasticsearch
Full message history: Only
lastMessageis stored.Attachments and payment content: Not indexed for search.
Precise audit data: Stored only in Firestore for compliance.
Elasticsearch is eventually consistent — it catches up quickly but may lag by a few seconds after large updates.
Failure & Recovery Behavior
ES writes happen after Firestore saves. If an ES update fails, the app logs an error but continues normally.
Inconsistencies (e.g., thread appears old or unread count mismatched) are temporary.
The next message, tag change, or periodic sync job automatically re-indexes the thread.
A maintenance utility (
updateThreadsInElastic) can re-sync all threads manually if needed.
Security & Role Access
Elasticsearch never exposes private data directly. All queries are filtered at runtime by the current user’s permissions:
Operations
Full access to all threads
Landlord
Threads where their ID appears in participantIds
Guest Coordinators
Subset where guestCoordinationActive = true
How It Helps in Practice
Chat loads instantly even with thousands of threads.
“Unread” and “Important” filters work in milliseconds.
Searching for a tag or property surfaces threads immediately.
Firestore stays lean — it handles message storage and real-time updates, not heavy queries.
Summary
Elasticsearch powers fast, searchable chat experiences in Hububb. It stores compact snapshots of threads — not the full chat history — and syncs automatically with Firestore. This combination delivers both reliability (Firestore) and speed (Elasticsearch), ensuring Support Chat and Guest Chat remain responsive and real-time even as the system scales.
Last updated