public static IListenerRegistration Subscribe <TModel, TViewModel, TKey>(IQuery query, SortedObservableCollection <TViewModel, TModel, TKey> viewModels, Func <TModel, TViewModel> getViewModel, Action?afterSnapshotProcessed = null) where TModel : BaseModel where TViewModel : IndexedCardViewModel <TModel> { viewModels.Clear(); return(query.AddSnapshotListener((snapshot, ex) => { if (snapshot is null) { viewModels.Clear(); } else if (viewModels.Any()) { foreach (var change in snapshot.DocumentChanges) { var doc = change.Document; if (change.Type == DocumentChangeType.Added) { viewModels.Add(getViewModel(doc.ToObject <TModel>() !)); } else { var vm = viewModels.SingleOrDefault(x => x.UID == doc.Id); if (vm is null) { return; } if (change.Type == DocumentChangeType.Modified) { viewModels.UpdateItem(vm, change.Document.ToObject <TModel>() !); } else { viewModels.Remove(vm); } } } } else if (!snapshot.IsEmpty) { snapshot.Documents.ForEach(x => viewModels.Add(getViewModel(x.ToObject <TModel>() !))); } afterSnapshotProcessed?.Invoke(); })); }