删除消息后,卸载重装应用,删除的消息又出现了

问题描述

同时删除本地消息和服务端历史消息后,卸载重装应用或者换设备登录,删除的消息重新出现。

原因分析

针对单聊会话、群聊会话,如果通过任何接口以传入时间戳的方式删除远端消息,服务端默认不会删除对应的离线消息补偿(该机制仅会在打开多设备消息同步开关后生效)。此时如果换设备登录或卸载重装,仍会因为消息补偿机制获取到已被删除的历史消息。

解决方案

方案一:推荐方案

如需彻底删除离线消息补偿,请提交工单,申请开通删除服务端历史消息时同时删除多端补偿的离线消息

如果开启了“多设备消息同步”服务,卸载重装应用,会触发“消息补偿”机制,默认会拉取到补偿时间内收发过的消息,如果删除的消息是在补偿时间内收发的,也会被拉取回来。

方案二:App 侧自行删除

1 在删除消息后,向会话发一条自定义消息,作为清除消息的标识。

在清除历史消息成功的回调中,删除会话,并且给该会话发一条不存储不计数的命令消息,作用是表示该会话历史消息已经被清除。

```objc
// 清除历史消息
- (void)clearMessage{
     [[RCCoreClient sharedCoreClient] clearHistoryMessages:self.conversationType targetId:self.targetId recordTime:0 clearRemote:YES success:^{
           NSLog(@"++++ 清除历史消息成功");
           NSLog(@"++++ 删除会话");
           [[RCCoreClient sharedCoreClient] removeConversation:self.conversationType targetId:self.targetId];
           // 发送删除消息和会话命令,name和data您自己定义
           RCCommandMessage *message = [[RCCommandMessage alloc] init];
           message.name = @"删除";
           message.data = [NSString stringWithFormat:@"%ld", self.conversationType];
           if (self.conversationType == ConversationType_SYSTEM) {
               NSLog(@"++++ 系统会话,删除命令发单聊消息");
               [[RCIM sharedRCIM] sendMessage:ConversationType_PRIVATE targetId:self.targetId content:message pushContent:nil pushData:nil success:^(long messageId) {
                   NSLog(@"++++ 删除命令发送成功");
               } error:^(RCErrorCode nErrorCode, long messageId) {
                   NSLog(@"++++ 删除命令发送失败 %ld", nErrorCode);
               }];
           } else {
               [self sendMessage:message pushContent:nil];
           }
       } error:^(RCErrorCode status) {
           NSLog(@"++++ 清除历史消息失败 %ld", status);
       }];
}
```
  1. 在消息接收监听中实现下面逻辑。

    当卸载重装后,如果在消息监听中监听到第 1 步中的自定义消息,再删除一次消息,如需删除会话,也要再执行一次。

    流程参考:

    代码示例:

     ```objc
      - (void)onRCIMReceiveMessage:(RCMessage *)message left:(int)left {
          if ([message.content isKindOfClass:[RCCommandMessage class]]) {
              RCCommandMessage *msg = (RCCommandMessage *)message.content;
              // 判断是否是自己发出的删除命令
              if ([msg.name isEqualToString:@"删除"] && message.messageDirection == MessageDirection_SEND) {
                  RCConversationType type = msg.data.integerValue;
                  // 接收到我发送的删除命令
                  // 获取该会话的最新一条消息
                  NSArray *array = [[RCIMClient sharedRCIMClient] getHistoryMessages:type targetId:message.targetId oldestMessageId:-1 count:1];
                  if (array.count > 0) {
                      // 该会话有消息
                      RCMessage *latestMsg = (RCMessage *)array[0];
                      if (latestMsg.sentTime > message.sentTime) {
                          // 最新一条消息的sentTime 大于 删除命令的sentTime ,说明用户在清除历史消息后该会话又有新消息。
                          // 此时只删除 命令消息 之前的消息,不删除会话。
                          [[RCIMClient sharedRCIMClient] clearHistoryMessages:type targetId:message.targetId recordTime:message.sentTime clearRemote:NO success:^{
                              NSLog(@"++++ 收到删除命令后清除成功");
                          } error:^(RCErrorCode status) {
                              NSLog(@"++++ 收到删除命令后清除失败%ld", status);
                          }];
                          // 根据时间戳清除之前的未读数。
                          [[RCCoreClient sharedCoreClient] clearMessagesUnreadStatus:type targetId:message.targetId time:message.sentTime completion:nil];
                      } else {
                          // 该用户清除历史消息后没有新消息
                          // 删除命令消息之前的消息,并且删除该会话
                          [[RCIMClient sharedRCIMClient] clearHistoryMessages:type targetId:message.targetId recordTime:message.sentTime clearRemote:NO success:^{
                              NSLog(@"++++ 收到删除命令后清除成功");
                          } error:^(RCErrorCode status) {
                              NSLog(@"++++ 收到删除命令后清除失败%ld", status);
                          }];
                          [[RCCoreClient sharedCoreClient] removeConversation:type targetId:message.targetId completion:nil];
                      }
                  } else {
                      // 无消息、无会话,不需要操作
                  }
              }
          }
      }
     ```
    

    特殊情况

    删除被踢出的群会话记录,无法向群里发消息,可以向当前用户自己发一条消息;