--- title: 获取历史消息 sidebar_position: 30 --- # 获取历史消息 获取历史消息可以仅从本地数据中获取,仅从远端获取,和同时从本地与远端获取。 ## 开通服务 从远端获取单群聊历史消息是指从融云服务端获取历史消息,该功能要求 App Key 已启用融云提供的**单群聊消息云端存储**服务。您可以在控制台 [IM 服务管理](https://console.rongcloud.cn/agile/formwork/advance/index)页面为当前使用的 App Key 开启服务。如果使用生产环境的 App Key,请注意仅 **IM 旗舰版**或 **IM 尊享版**可开通该服务。具体功能与费用以[融云官方价格说明](https://www.rongcloud.cn/pricing)页面及[计费说明](https://help.rongcloud.cn/t/topic/123)文档为准。 **提示**:请注意区分历史消息记录与离线消息?。融云针对单聊、群聊、系统消息默认提供最多 7 天(可调整)的离线消息缓存服务。客户端上线时 SDK 会自动收取离线期间的消息,无需 App 层调用 API。 ## 从本地数据库中获取单条消息:消息 id {#getmsglocal} 根据消息 ID 从本地数据库中获取单条消息。 ```ts let messageId = 123; IMEngine.getInstance().getMessageById(messageId).then(result => { if (EngineError.Success !== result.code) { // 获取消息失败 return; } if (!result.data) { // 消息不存在 return; } // 消息体 let msg = result.data as Message; }); ``` | 参数 | 类型 | 说明| |:-----------------|:---------------------------------|:------------------------------------------| | messageId | number | 消息的 ID | ## 从本地数据库中获取单条消息:消息 uid {#getmsglocal} 根据消息 uid 从本地数据库中获取单条消息。 ```ts let msgUid = "CG5U-IGFN-F6S6-CVTR"; IMEngine.getInstance().getMessageByUid(msgUid).then(result => { if (EngineError.Success !== result.code) { // 获取消息失败 return; } if (!result.data) { // 消息不存在 return; } // 消息体 let msg = result.data as Message; }); ``` | 参数 | 类型 | 说明| |:-----------------|:---------------------------------|:------------------------------------------| | msgUid | string | 消息 唯一 id,发送成功的消息才有 uid | ## 从本地数据库中分页获取批量消息:消息 id {#getmsglocal} 查询指定会话存储在本地数据库中的历史消息,并返回消息对象列表。 ```ts let conId = new ConversationIdentifier(); conId.conversationType = ConversationType.Private; conId.targetId = "会话 id"; let option: IGetLocalMsgByIdOption = { objNameList: objNameList, messageId: messageId, beforeCount: beforeCount, afterCount: afterCount } IMEngine.getInstance().getHistoryMessagesById(conId, option).then(result => { if (EngineError.Success !== result.code) { // 获取消息失败 return; } if (!result.data) { // 消息不存在 return; } // 消息体 let msg = result.data as List; }); ``` 参数 IGetLocalMsgByIdOption 的详细描述 ```ts /** * 获取本地消息的配置 * * beforeCount afterCount 总共分为四种情况 * ``` * 1. beforeCount > 0 && afterCount > 0,将获取 beforeCount + {messageId} + afterCount 的消息 * 2. beforeCount > 0 && afterCount == 0,将获取 beforeCount + {messageId} 的消息 * 3. beforeCount == 0 && afterCount > 0,将获取 {messageId} + afterCount 的消息 * 4. beforeCount == 0 && afterCount == 0,将获取 {messageId} * ``` * @version 1.0.0 */ interface IGetLocalMsgByIdOption { /** * objectName 集合,为空的话代表获取所有类型的本地消息 * * 有效值的话代表获取指定类型的消息 */ objNameList?: List, /** * 消息本地数据库 ID */ messageId: number, /** * 在 messageId 之前的消息个数,取值 >=0 * @discussion beforeCount 如果传入 10 ,但是获取的个数不足时说明往前没有更多的消息了 */ beforeCount: number, /** * 在 messageId 之后的消息个数,取值 >=0 * @discussion afterCount 如果传入 10 ,但是获取的个数不足时说明往后没有更多的消息了 */ afterCount: number, } ``` ## 从本地数据库中分页获取批量消息:时间戳 {#getmsglocal} 查询指定会话存储在本地数据库中的历史消息,并返回消息对象列表。 ```ts let conId = new ConversationIdentifier(); conId.conversationType = ConversationType.Private; conId.targetId = "会话 id"; let option: IGetLocalMsgByTimeOption = { objNameList: objNameList, time: time, beforeCount: beforeCount, afterCount: afterCount } IMEngine.getInstance().getHistoryMessagesByTime(conId, option) .then(result => { if (EngineError.Success !== result.code) { // 获取消息失败 return; } if (!result.data) { // 消息不存在 return; } // 消息列表 let msgList = result.data as List; }); ``` 参数 IGetLocalMsgByTimeOption 的详细描述 ```ts /** * 获取本地消息的配置 * * beforeCount afterCount 总共分为四种情况 * ``` * 1. beforeCount > 0 && afterCount > 0,将获取 beforeCount + {time} + afterCount 的消息 * 2. beforeCount > 0 && afterCount == 0,将获取 beforeCount + {time} 的消息 * 3. beforeCount == 0 && afterCount > 0,将获取 {time} + afterCount 的消息 * 4. beforeCount == 0 && afterCount == 0,将获取 {time} * ``` * @version 1.0.0 */ interface IGetLocalMsgByTimeOption { /** * objectName 集合,为空的话代表获取所有类型的本地消息 * * 有效值的话代表获取指定类型的消息 */ objNameList?: List, /** * 毫秒时间戳 * 初次可以传入当前时间: Date.now() 或者传入会话的 lastSentTime * @see Conversation */ time: number, /** * 在 messageId 之前的消息个数,取值 >=0 * @discussion beforeCount 如果传入 10 ,但是获取的个数不足时说明往前没有更多的消息了 */ beforeCount: number, /** * 在 messageId 之后的消息个数,取值 >=0 * @discussion afterCount 如果传入 10 ,但是获取的个数不足时说明往后没有更多的消息了 */ afterCount: number, } ``` ### 获取服务端批量消息 ```ts let conId = new ConversationIdentifier(); conId.conversationType = ConversationType.Private; conId.targetId = "会话 id"; let option: IGetRemoteMsgOption = { time: time, count: 10, order: Order.Descending, isCheckDup: true } IMEngine.getInstance().getRemoteHistoryMessages(conId, option).then(result => { if (EngineError.Success !== result.code) { // 获取消息失败 return; } if (!result.data) { // 消息不存在 return; } // 消息列表 let msgList = result.data as List; }); ``` 参数 IGetRemoteMsgOption 的详细描述 ```ts /** * 获取远端消息配置 * @version 1.0.0 */ interface IGetRemoteMsgOption { /** * 毫秒时间戳 * 初次可以传入当前时间: Date.now() 或者传入 Conversation.lastSentTime */ time: number, /** * 消息个数,[1 ~ 100] */ count: number, /** * 获取的消息顺序 * * Descending: 获取比 time 小的消息列表 * * Ascending:获取比比 time 大的消息列表 */ order: Order, /** * 是否包含本地已存在消息 * * @discussion true: 拉取回来的消息全部返回 ; false: 拉取回来的消息只返回本地数据库中不存在的 */ isCheckDup: boolean, } ``` ### 获取本地批量未读 @ 消息 ```ts let conId = new ConversationIdentifier(); conId.conversationType = ConversationType.Private; conId.targetId = "会话 id"; let option: ICountOption = { count: 5, order: Order.Descending }; IMEngine.getInstance().getUnreadMentionedMessages(conId, option) .then(result => { if (EngineError.Success !== result.code) { // 获取消息失败 return; } if (!result.data) { // 消息不存在 return; } // 消息列表 let msgList = result.data as List; }); ``` 参数 ICountOption 的详细描述 ```ts /** * 个数配置 * @version 1.0.0 */ interface ICountOption { /** * 消息个数 */ count: number, /** * 获取数据顺序 * @see Order */ order: Order, } ``` ### 获取本地第一条未读消息 ```ts let conId = new ConversationIdentifier(); conId.conversationType = ConversationType.Private; conId.targetId = "会话 id"; IMEngine.getInstance().getFirstUnreadMessage(conId) .then(result => { if (EngineError.Success !== result.code) { // 获取消息失败 return; } if (!result.data) { // 消息不存在 return; } let msg = result.data as Message; }); ```