@f-miyu
I have a complex scenario (a chat), I get the conversations like this:
var listener = CrossCloudFirestore.Current.Instance.Collection(Settings.ChatsCollection)
.WhereArrayContains(Settings.UserIds, MyUserId)
.AddSnapshotListener(async (snapshot, error) =>
{
if (error != null)
{
ChatsTabPageState = LayoutState.Error;
ChatRooms.Clear();
}
else if (snapshot?.IsEmpty is true || snapshot is null)
{
ChatsTabPageState = LayoutState.Empty;
ChatRooms.Clear();
}
else
{
foreach (var documentChange in snapshot.DocumentChanges)
{
ChatRoom chatRoom;
switch (documentChange.Type)
{
case DocumentChangeType.Added:
chatRoom = documentChange.Document.ToObject<ChatRoom>();
var rChatRoom = ChatRooms.FirstOrDefault(f => f.Id == chatRoom.Id);
if (rChatRoom != null) break;
ChatRooms.Add(chatRoom);
break;
case DocumentChangeType.Modified:
chatRoom = documentChange.Document.ToObject<ChatRoom>();
var modChatRoom = ChatRooms.FirstOrDefault(f => f.Id == chatRoom.Id);
if (modChatRoom is null) break;
if (!modChatRoom.IsPrivate)
{
modChatRoom.Title = chatRoom.Title;
modChatRoom.Image = chatRoom.Image;
modChatRoom.PendingUserIds = chatRoom.PendingUserIds;
}
modChatRoom.UserIds = chatRoom.UserIds;
modChatRoom.FCMTokens = chatRoom.FCMTokens;
modChatRoom.RecentMessage = chatRoom.RecentMessage;
break;
case DocumentChangeType.Removed:
chatRoom = documentChange.Document.ToObject<ChatRoom>();
var removeChatRoom = ChatRooms.FirstOrDefault(f => f.Id == chatRoom.Id);
if (removeChatRoom is null) break;
ChatRooms.Remove(removeChatRoom);
break;
}
if (documentChange.Type is DocumentChangeType.Added)
{
chatRoom = documentChange.Document.ToObject<ChatRoom>();
//UnreadListener
ChatsUnreadMessagesAddListener(chatRoom.Id);
}
}
Device.BeginInvokeOnMainThread(() =>
{
var roomsOrder = ChatRooms.OrderByDescending(chatRoom =>
chatRoom.RecentMessage.CreatedAt).ToList();
ChatRooms.ReplaceRange(roomsOrder);
});
if (ChatsTabPageState != LayoutState.Success)
ChatsTabPageState = LayoutState.Success;
}
});
chatsListener.Add(listener);
UnreadListener:
var listener = CrossCloudFirestore.Current.Instance.Collection(Settings.UnreadChatMessagesCollection)
.Document(chatId)
.Collection(Settings.MessagesCollection)
.Document(MyUserId)
.AddSnapshotListener((snapshot, error) =>
{
if (error != null)
{
}
else if (snapshot != null)
{
var unreadMessage = snapshot.ToObject<UnreadMessage>();
Device.BeginInvokeOnMainThread(() =>
{
var chatRoom = ChatRooms.FirstOrDefault(f => f.Id == unreadMessage.ChatId);
chatRoom.UnreadMessages = unreadMessage.Total;
});
}
});
chatsListener.Add(listener);
The problem seems that sometimes the collection is modified and at the same time sorted and I get:
System.ArgumentOutOfRangeException Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index
This only happens if you click the push notification that I get a new message and go to the conversation. If I open the app and go to the chats tab and click on the conversation, the exception does not jump.
If I remove this code everything seems to be fine, but I need to always sort the collection, but I cannot control how fast new messages are received. Any ideas? should I change the focus?
@f-miyu I have a complex scenario (a chat), I get the conversations like this:
UnreadListener:
The problem seems that sometimes the collection is modified and at the same time sorted and I get:
System.ArgumentOutOfRangeException Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index
This only happens if you click the push notification that I get a new message and go to the conversation. If I open the app and go to the chats tab and click on the conversation, the exception does not jump.
If I remove this code everything seems to be fine, but I need to always sort the collection, but I cannot control how fast new messages are received. Any ideas? should I change the focus?