Persisted Controller 🔄
A controller in flutter_chat_ui
acts as the source of truth for your chat data, primarily managing the messages. When implementing a persisted controller, understanding how your data source handles order is crucial. There are primarily two types of data sources to consider: ordered and non-ordered.
Ordered Data Sources
Section titled “Ordered Data Sources”An ordered data source maintains a specific sequence for its elements. A simple example is an array, which is utilized by the InMemoryChatController
provided by the flutter_chat_core
package.
With an array-based (and thus ordered) data source, operations are straightforward:
- You can insert messages at any specific index.
- You can update messages at any specific index.
- You can simply return the array from the
messages
getter.
However, it’s important to note that the InMemoryChatController
is, by its nature, not persisted. While simple to work with, its data will be lost when the application session ends.
Non-Ordered Data Sources (Common for Persisted Controllers)
Section titled “Non-Ordered Data Sources (Common for Persisted Controllers)”For persisted controllers, you will most likely be working with some form of database.
Databases with Implicit Ordering (e.g., Auto-Increment Keys)
Section titled “Databases with Implicit Ordering (e.g., Auto-Increment Keys)”If your chosen database supports inherent ordering (for instance, through auto-incrementing primary keys), and you don’t anticipate needing to insert messages into the middle of an existing conversation, this will work similarly to the InMemoryChatController
. You won’t be able to insert or update at a specific index, but you can still simply return the ordered data directly from the database.
Databases with No Inherent Ordering
Section titled “Databases with No Inherent Ordering”Many databases will not guarantee any specific order when you retrieve data. They operate without auto-increment keys or an intrinsic sense of sequence.
In this scenario:
- You typically add new messages to the database without specifying a position.
- You cannot reliably implement functions like
insertMessage({int? index})
orinsertAllMessages({int? index})
because there’s no stable concept of an “index” directly from the database.
Recommended Approach:
- Insertion: Add messages to the database as they arrive.
- Retrieval (
messages
getter):- Fetch all relevant messages from your data source.
- Sort these messages based on a reliable key before returning them. A common and effective choice is a
createdAt
timestamp, serialized to milliseconds for precise ordering.
- Benefits:
- This approach consistently ensures the correct message order in your UI.
- It robustly handles offline-first scenarios. When syncing with a backend, new and historical messages can be seamlessly integrated and correctly ordered because the sorting logic remains consistent.
A practical example of this approach using Hive CE can be found in the example project - HiveChatController.