turms
turms copied to clipboard
add fileds for queryPrivateConversation readDate
query queryPrivateConversation return result as follow:
Response{timestamp: 2023-08-19 13:04:17.694, requestId: 3124259594, code: 1000, data: [ownerId: 1
targetId: 2
readDate: 1692421447927
]}
and readDate value is changed when updatePrivateConversationReadDate(targetId))
called, but this method can only change conversation's "targetId"readDate, I would like to changes conversation owner's readDate as well, and can get it from same api,
expected return would be like
Response{timestamp: 2023-08-19 13:04:17.694, requestId: 3124259594, code: 1000, data: [ownerId: 1
targetId: 2
targetReadDate: 1692421447927
ownerReadDate: 1692421447927
]}
I would like to use these two value to calculte unReadMessage after readDate, so it needs owner side and target side
I would like to use these two value to calculte unReadMessage after readDate, so it needs owner side and target side
- You should better store current user information on their local devices, e.g. the read date of each conversation. Turms is designed in this way to not store such data on the server side for better performance and flexibility.
So we have no plan to add something like
ownerReadDate
currently. - You can use
turmsClient.messageService.queryMessagesWithTotal(...)
to count unread messages by passingdeliveryDateStart
as the current user's last read date of conversations, and setmaxCount
to99
for example to only query messages in a reasonable range for your scenarios. - And there is another solution to count unread messages that we will support in the future, and you can read https://github.com/turms-im/turms/issues/1130#issuecomment-1432402100 if you are interested in.
Thanks for reply. I had checked #1130 , still cannot clear my head. I will share more info with how I count privateConversations and groupCversations unreadMessage.
1. Private conversation
Private conversation cases pre-condiction:
- There are 2 users , user id = 1, user id = 2, I will simply call them user1 and user2.
- They had made a privateConversation
{ownerId = 1, targetId = 2, readDate = xxx}
and store on server can be query by queryPrivateConversation(). - When userx offline, other will send offline message to make "unread message".
Private conversation simulation cases:
Case 1: Count user2's unread when offline change to online
-
in the last chat, user2 has local value "localReadDate" of this conversation, value will saved to local when user read message every time, and also I will call
updatePrivateConversationReadDate(targetId =2, readDate = xxx)
to update user2's readDate server value. Theoretically, these two values(localReadDate,readDate)store in local and server should be consistent, then make user2 offline. -
When user2 became online, I will call queryPrivateConveration(), return [{ownerId,targetId,readDate}], handle it properly, because readDate is set by targetId = 2, which is user2, I defined: 'return value readDate is higher priority than localReadDate so I wll update localReadDate again'.
/// count this specific converstion
if (readDate != 0 ){
localReadDate = readDate;
}
int user2UnreadCount = 0;
final messages = await client.messageService.queryMessagesWithTotal(
fromIds: {1.toInt64()}, // user2's messages from user1
areGroupMessages: false,
deliveryDateStart: DateTime.fromMillisecondsSinceEpoch(localReadDate),
maxCount: 1,
descending: true,
);
if (messages.data.isEmpty) {
user2UnreadCount = 0
} else {
user2UnreadCount = messages.data.first.total;
}
Through these steps, I can correctly get user2's unread messages.
Case 2: Count user2's unread when login new device
- When user2 login on new device, user2 has no local value localReadDate of this conversation, call queryPrivateConveration api, will return {ownerId,targetId,readDate}, handle it properly, found needed converastion, because readDate is set by targetId = 2, which is user2, so now I known user2's readDate, even I have no local date of localReadDate.
if (readDate != 0){
localReadDate = readDate;
}
int user2UnreadCount = 0;
final messages = await client.messageService.queryMessagesWithTotal(
fromIds: {1.toInt64()}, // user2's messages from user1
areGroupMessages: isGroup,
deliveryDateStart: DateTime.fromMillisecondsSinceEpoch(localReadDate),
maxCount: 1,
descending: true,
);
if (messages.data.isEmpty) {
user2UnreadCount = 0
} else {
user2UnreadCount = messages.data.first.total;
}
Through these steps, I can also correctly get user2's unread messages count on new device with no localReadDate.
Case 3: Count user1's unread when offline change to online
-
user1 has record value "localReadDate" of this conversation, value will saved to local when user read message every time, but I cannot call
updatePrivateConversationReadDate(targetId, readDate = xxx)
to update server value. because user1 is Owner , not Target. , then make user1 offline. -
When user1 became online, I will call queryPrivateConveration api, return [{ownerId,targetId,readDate}], handle it properly, found needed converastion. because readDate is represent to targetId = 2, it's belong to user2, user1 cannot use it.
final localReadDate = getConversationLocalReadDate(...);
int user1UnreadCount = 0;
final messages = await client.messageService.queryMessagesWithTotal(
fromIds: {2.toInt64()}, // user1's messages from user2
areGroupMessages: false,
deliveryDateStart: DateTime.fromMillisecondsSinceEpoch(localReadDate),
maxCount: 1,
descending: true,
);
if (messages.data.isEmpty) {
user1UnreadCount = 0
} else {
user1UnreadCount = messages.data.first.total;
}
Through these steps, I can correctly get user1's unread messages. The premise is that user1 has correctly recorded localReadDate locally.
Case 4: Count user1's unread when login new device
- When user1 login on new device, user1 has no local value localReadDate of this conversation, I will call queryPrivateConveration api, return [{ownerId,targetId,readDate}], handle it properly, found needed converastion. because readDate is represent to targetId = 2, it's belong to user2, user1 cannot use it, now there is no way user1 can know owner's readDate of this conversation. use localReadDate = 0 instead.
localReadDate = 0; /// init local value is default to 0
int user2UnreadCount = 0;
final messages = await client.messageService.queryMessagesWithTotal(
fromIds: {2.toInt64()}, // user1's messages from user2
areGroupMessages: isGroup,
deliveryDateStart: DateTime.fromMillisecondsSinceEpoch(localReadDate),
maxCount: 1,
descending: true,
);
if (messages.data.isEmpty) {
user2UnreadCount = 0
} else {
user2UnreadCount = messages.data.first.total;
}
Through these steps, I can not correctly get user1's unread messages count on new device, counts will be all meesages sent to user1 from deliveryDateStart = 0.
Case result
num | case name | get unread correctly |
---|---|---|
1 | count user2's unread when user2 offline->online | [✓] |
2 | count user2's unread when user2 login new device | [✓] |
3 | count user1's unread when user1 offline->online | [✓] |
4 | count user1's unread when user1 login new device | [✗] |
2. Group conversation
Count group conversation almost same with private conversation, but the diff is queryGroupConversation return fields has "memberIdToReadDate" list
[
{memberId,readDate}
{memberId,readDate}
]
it store every member's readDate on server, and every member can call updateGroupConversationReadDate to update themselves readDate in this group too. memberIdToReadDate list can cover all cases like private converstions, let every group member's can count correct unread number of whatever they offline or login on new device.
Issue
If queryPrivarionConverstion return fields only have readDate can represent to targetId's readDate, without owner's, above case num 4 will feeling is a pity.
This is quite a long description, if there is any unclear describe please let me know.
In a word, you want to sync the read date between different devices?
Yes, If I read message on android device, ios device unread counts will sync too.
Yes, If I read message on android device, ios device unread counts will sync too.
I will add support for this feature this weekend. By the way, Turms is not designed to support synchronizing data between devices currently, but data sync features will be supported later.