Get message history
Function overview
This document applies to the following platforms: iOS, Android, macOS, Windows and Web.
You can use ZIM APIs to query all historical messages or specified messages in one-to-one chats, group chats, or room conversations. During the query process, the ZIM SDK will first retrieve messages from the local database cache; when the local cache is incomplete, the SDK will automatically initiate a query request to the ZIM server.
This document will provide a detailed introduction on how to use ZIM SDK interfaces to implement the functionality of retrieving historical messages for one-to-one chats, group chats, and rooms.
- Messages cached in the local database are not subject to the server's historical message storage duration limit, but when querying the server, only messages within the historical message storage duration can be retrieved.
- Except for command messages and barrage messages, historical messages of other types can be retrieved through this feature.
- You can read Send and receive messages, Delete messages, and other docs based on your needs.
- The number of days for historical message storage is related to the plans. For details, please refer to the "Plan Differences" section in Pricing.
Get the full message history
After logging in to ZIM SDK, users can use the queryHistoryMessageByConversationID method to retrieve the message history of one-to-one chats
, group chats
, and rooms chats
by providing the parameters conversationID and config.
Taking the example of client A retrieving the conversation history with client B in a one-on-one chat:
- Client A and B log in to the ZIM SDK and send/receive one-on-one chat messages to each other.
- When client A needs to retrieve the conversation records with B:
- Client A first logs in to the ZIM SDK.
- Client A calls the queryHistoryMessageByConversationID interface and passes the conversationID and config parameters to start retrieving.
- The retrieved results will be notified to client A through the ZIMMessageQueriedCallback callback interface.
// Get historical messages in a one-on-one chat
ArrayList<ZIMMessage> curMessageList = new ArrayList();
String conversationID = "xxxx";
// Retrieve 30 messages at a time, starting from the end
ZIMMessageQueryConfig config = new ZIMMessageQueryConfig();
// For the first retrieval, nextMessage is null
config.nextMessage = null;
config.messageCount = 30;
config.reverse = true;
ZIMMessageQueriedCallback callback = new ZIMMessageQueriedCallback() {
@Override
public void onMessageQueried(ArrayList<ZIMMessage> messageList, ZIMError errorInfo) {
// Developers can use this callback to listen for the retrieved message list.
curMessageList.addAll(0, messageList);
// When scrolling down to the topmost message on the screen, retrieve earlier messages
if (fetchMore) {
// For subsequent pagination, nextMessage is the last message in the currently retrieved message list
config.nextMessage = messageList.get(messageList.size() - 1);
zim.queryHistoryMessage(conversationID, ZIMConversationType.Peer, config, callback);
}
}
}
zim.queryHistoryMessage(conversationID, ZIMConversationType.Peer, config, callback);
1
// Get the message history.
std::string conversationID = "xxxx";
// Get session history messages from late to early. The number of historical messages is 20 at a time.
zim::ZIMTextMessage *message = nullptr;
zim::ZIMMessageQueryConfig config;
config.count = 20;
config.reverse = true;
zim_->queryHistoryMessage(conversationID,zim::ZIMConversationTypePeer,config,callback);
1
// Retrieve historical messages for one-on-one chats
const curMessageList: ZIMMessage[] = [];
const conversationID = '';
const conversationType = 0;
// Retrieve 30 messages each time, starting from the latest message
const config: ZIMMessageQueryConfig = {
nextMessage: null, // Set nextMessage to null for the first retrieval
count: 30,
reverse: true
}
function queryMessageCallback({ messageList }) {
curMessageList.push(...messageList);
// When scrolling down to the topmost message on the screen, retrieve earlier messages
if (fetchMore && messageList.length > 0) {
// For subsequent pagination, set nextMessage to the first message in the current retrieved message list
config.nextMessage = messageList[0];
zim.queryHistoryMessage(conversationID, conversationType, config).then(queryMessageCallback);
}
}
zim.queryHistoryMessage(conversationID, conversationType, config).then(queryMessageCallback);
1
// Get the historical messages of a one-on-one chat
// Get the conversation history messages from the back to the front, retrieve 30 messages each time
ZIMMessageQueryConfig config = ZIMMessageQueryConfig();
// For the first retrieval, nextMessage is null
config.nextMessage = null;
config.count = 30;
config.reverse = true;
await ZIM
.getInstance()!
.queryHistoryMessage('conversationID', ZIMConversationType.peer, config)
.then((value) => {
// Triggered when successful
// Developers can listen to this callback to obtain the retrieved message list.
// When the finger scrolls down to the topmost message on the screen, retrieve earlier messages
// Save the frontmost message as the anchor for the messages
if (fetchMore) {
// For subsequent pagination retrieval, nextMessage is the first message in the currently retrieved message list
config.nextMessage = value.messageList[0],
// Recursive retrieval
}
})
.catchError((onError) {
// Triggered when failed
});
1
// Get the chat history of a one-on-one chat
NSString *conversationID = @"xxxx";
// Retrieve messages from the back to the front, 20 messages at a time
ZIMMessageQueryConfig *config = [[ZIMMessageQueryConfig alloc] init];
config.count = 20;
config.reverse = true;
// nextMessage is null for the first retrieval
config.nextMessage = nil
[zim queryHistoryMessageByConversationID:conversationID conversationType:conversationType config:config callback:^(NSArray<ZIMMessage *> * _Nonnull messageList, ZIMError * _Nonnull errorInfo) {
// Developers can listen to this callback to get the message list.
// When scrolling down to the topmost message on the screen, retrieve earlier messages
// Save the frontmost message as the anchor for the messages
if (fetchMore) {
// nextMessage is the first message in the current retrieved message list for subsequent pagination retrieval
config.nextMessage = messageList[0];
// Recursively call the retrieval function
}
}];
1
Get specific messages
ZIM supports querying specific messages in a one-to-one or group conversation based on messageSeq
(the sequence number of the message in the conversation) list (up to a maximum of 10) by calling queryMessagesByMessageSeqs.
This interface is used when you only know the messageSeq
of a message and do not know the complete structure of the message. For example, if a message in a conversation replies to a historical message, members of the conversation can use the repliedInfo.messageSeq
of the reply to obtain the messageSeq
of the historical message. At this time, you can call this interface to obtain the complete structure of the historical message.
ArrayList<Long> messageSeqs = new ArrayList<>(); // The maximum length is 10
String conversationID = "YOUR_CONVERSATION_ID";
ZIMConversationType conversationType = ZIMConversationType.PEER; // Conversation type: one-to-one: ZIMConversationType.PEER, group: ZIMConversationType.GROUP
ZIM.getInstance().queryMessages(messageSeqs, conversationID, conversationType, new ZIMMessageQueriedCallback() {
@Override
public void onMessageQueried(String conversationID, ZIMConversationType conversationType, ArrayList<ZIMMessage> messageList, ZIMError errorInfo) {
if(errorInfo.code == ZIMErrorCode.SUCCESS) {
// Query succeeded
} else {
// Query failed
}
}
});
1
std::vector<long long> messageSeqs; // The maximum length is 10
std::string conversationID = "YOUR_CONVERSATION_ID";
ZIMConversationType conversationType = ZIM_CONVERSATION_TYPE_PEER; // Conversation type: one-to-one: ZIM_CONVERSATION_TYPE_PEER, group: ZIM_CONVERSATION_TYPE_GROUP
ZIM::getInstance()->queryMessages(messageSeqs, conversationID, conversationType, [=](const std::string &conversationID, ZIMConversationType conversationType, const std::vector<std::shared_ptr<ZIMMessage>> &messageList, const ZIMError &errorInfo) {
if(errorInfo.code == ZIM_ERROR_CODE_SUCCESS) {
// Query successful
} else {
// Query failed
}
});
1
const messageSeqs = []; // The maximum length is 10
const conversationID = '';
const conversationType = 0; // Conversation type: one-to-one: 0, group: 2
zim.queryMessages(messageSeqs, conversationID, conversationType)
.then(({ messageList }) => {
// Query successful
})
.catch((err) => {
// Query failed
});
1
List<int> messageSeqs = []; // The maximum length is 10
String conversationID = "YOUR_CONVERSATION_ID";
ZIMConversationType conversationType = ZIMConversationType.peer; // Conversation type: one-to-one: ZIMConversationTypePeer, group: ZIMConversationTypeGroup
ZIM.getInstance()?.queryMessages(messageSeqs, conversationID, conversationType).then((value) {
// Query successful
}).catchError((onError){
if(onError is PlatformException){
// Query failed
}
});
1
NSArray<NSNumber *> messageSeqs = @[]; // The maximum length is 10
NSString *conversationID = @"YOUR_CONVERSATION_ID";
ZIMConversationType conversationType = ZIMConversationTypePeer; // Conversation type: one-to-one: ZIMConversationTypePeer, group: ZIMConversationTypeGroup
[[ZIM getInstance] queryMessagesByMessageSeqs:messageSeqs conversationID:conversationID conversationType:conversationType callback:^(NSString * _Nonnull conversationID, ZIMConversationType conversationType, NSArray<ZIMMessage *> * _Nonnull messageList, ZIMError * _Nonnull errorInfo) {
if(errorInfo.code == ZIMErrorCodeSuccess) {
// Query successful
} else {
// Query failed
}
}];
1