【发布时间】:2021-05-09 05:04:42
【问题描述】:
我正在尝试使用 Xamarin Forms 创建跨平台应用程序。我决定使用 Firestore 作为我的应用程序的数据库。
我正在尝试将聊天功能添加到我的应用程序中,但我正在努力实现实时收听功能。我已经创建了一个 ViewModel 类,其中包含一个聊天的 ObservableCollection,供 UI 中的 ListView 使用。
public class ChatsVM
{
public ObservableCollection<Chat> Chats { get; set; }
public ChatsVM()
{
Chats = new ObservableCollection<Chat>();
ReadMessages();
}
public async void ReadMessages()
{
User currentUser = await DependencyService.Get<IFirebaseAuthenticationService>().GetCurrentUserProfileAsync();
IList<Chat> chatList = await DependencyService.Get<IChatService>().GetChatsForUserAndListenAsync(currentUser.IsLandlord, currentUser.Id);
foreach (var chat in chatList)
{
Chats.Add(chat);
}
}
}
我还创建了从 Firestore 获取数据的服务。在服务方面(例如显示 Android 服务)我使用标准列表来保存聊天对象
List<Chat> Chats;
bool hasReadChats;
GetChatsForUserAndListenAsync 方法将快照侦听器添加到我的查询并将事件传递给 OnEvent 方法。
public async Task<IList<Chat>> GetChatsForUserAndListenAsync(bool isLandlord, string userId)
{
string fieldToSearch;
if (isLandlord)
{
fieldToSearch = "landlordId";
}
else
{
fieldToSearch = "tenantId";
}
try
{
// Reset the hasReadChats value.
hasReadChats = false;
CollectionReference collectionReference = FirebaseFirestore.Instance.Collection(Constants.Chats);
// Get all documents in the collection and attach a OnCompleteListener to
// provide a callback function.
collectionReference.WhereEqualTo(fieldToSearch, userId).AddSnapshotListener(this);
// Wait until the callback has finished reading and formatting the returned
// documents.
for (int i = 0; i < 10; i++)
{
await System.Threading.Tasks.Task.Delay(100);
// If the callback has finished, continue rest of the execution.
if (hasReadChats)
{
break;
}
}
return Chats;
}
catch (FirebaseFirestoreException ex)
{
throw new Exception(ex.Message);
}
catch (Exception)
{
throw new Exception("An unknown error occurred. Please try again.");
}
}
public void OnEvent(Java.Lang.Object value, FirebaseFirestoreException error)
{
var snapshot = (QuerySnapshot) value;
if (!snapshot.IsEmpty)
{
var documents = snapshot.Documents;
Chats.Clear();
foreach (var document in documents)
{
Chat chat = new Chat
{
Id = document.Id,
LandlordId = document.Get("landlordId") != null ? document.Get("landlordId").ToString() : "",
TenantId = document.Get("tenantId") != null ? document.Get("tenantId").ToString() : ""
};
//JavaList messageList = (JavaList) document.Get("messages");
//List<Message> messages = new List<Message>();
// chat.Messages = messages;
Chats.Add(chat);
}
hasReadChats = true;
}
}
如何将事件处理程序对该列表所做的任何更改传播到我的 VM 类中的 ObservableCollection?
【问题讨论】:
-
使用 MessagingCenter 从 Android 向 Forms VM 发送一条包含任何新消息的消息
-
这不是一个坏主意。但我需要传递对象。每当在数据库上触发事件并让 VM 类重新读取列表时传递消息是否有效?
-
可以在消息中传递强类型参数
-
好的,我会试一试,告诉你进展如何。谢谢杰森!
-
很好的解决方案@Jason。做了我需要它做的事情。非常感谢!
标签: c# listview xamarin.forms mvvm google-cloud-firestore