使用Swift中的Firebase计算看不见的消息

我正在尝试编写聊天应用程序代码。

我想计算一些未被查看的消息(看不见)。

我的数据库看起来像这样:

user-messages | |_messages | |_UserID1 | | | |_UserID2 | | | |_ MessageID1 | |_ MessageID2 | |_ MessageID3 | |_ etc... | |_UserID2 | | | |_UserID1 | | | |_ MessageID1 | |_ MessageID2 | |_ MessageID3 | |_ etc... 

而对于Messages对象:

 messages | |_messageID1 | | | |_ notViewed: false / true | |_ text: "Message text" | |_ timestamp: 1522230692 | |_ etc... | |_messageID2 | | | |_ notViewed: false / true | |_ text: "Message text" | |_ timestamp: 1522230692 | |_ etc... 

我到达以获取链接到特定用户的所有消息ID:

 var REF_MESSAGE = Database.database().reference().child("messages") var REF_USER_MESSAGE = Database.database().reference().child("user-messages").child("messages") func fetchUnviewedMessages(withId id: String, completion: @escaping (Int) -> Void ) { REF_USER_MESSAGE.child(id).observe(.childAdded) { (snapshot) in let userId = snapshot.key as String self.REF_USER_MESSAGE.child(id).child(userId).observe(.childAdded, with: { (snapshot) in let messageId = snapshot.key // This part is where I have a problem self.fetchMessageNotViewed(messageId, completion: { (nbMessageNotRead) in completion(nbMessageNotRead) }) }) } } 

但我不知道我需要对该列表做些什么,以观察看不见的消息的数量……

我尝试过,但没有成功:

 func fetchMessageNotViewed(_ messageId: String, completion: @escaping (Int) -> Void) { guard let currentUid = Api.User.CURRENT_USER?.uid else { return } REF_MESSAGE.child(messageId).queryOrdered(byChild: "notViewed").queryEqual(toValue: true).observe(.value, with: { (snapshot) in let count = Int(snapshot.childrenCount) print(count) }, withCancel: nil) } 

根据@KevinB的要求

您可以使用我的逻辑在消息弹出窗口中显示计数器

步骤:-1 WebService调用/ Firebase Fetch:

在app中获取消息数据的数组。在我的情况下,我在响应中有一组消息,并将其计数存储为userDefault。 例如: –

 UserDefaults.standard.set(arrMessageData.count, forKey: "messageCount") 

步骤:-2读取消息时设置Counter-Zero或使用新值追加旧值

案例:1阅读消息

在我的情况下,我有一个单独的弹出窗口来阅读消息。 当弹出窗口打开时,我强行将userDefault值的值设为0

 UserDefaults.standard.set(0, forKey: "messageCount") 

案例:1如果未读取消息

在这种情况下,如果没有打开弹出窗口,那么在这种情况下,userDefault中会有一些值。 在这种情况下,首先获取userDefault中的当前计数,然后创建WSCall并获取新计数并添加两者,然后保存在相同的密钥中。

注意: –使用在userDefault中存储计数器的想法是因为它可以在应用程序的任何地方访问,并且可以直接显示在任何标签或按钮中。

我们可以利用复合值来相当容易地处理这个问题。

对Firebase结构消息节点进行简单更改:

 messages | |_messageID1 | | | |_ notViewed: false / true | |_ text: "Message text" | |_ timestamp: 1522230692 | |_ forUid_status: "UserId1_unread" //<- Compound value | |_ etc... | |_messageID2 | | | |_ notViewed: false / true | |_ text: "Message text" | |_ timestamp: 1522230692 | |_ forUid_status: "UserId1_read" //<- Compound value | |_ etc... 

然后一个简单的查询将显示UserId1未读消息的计数

 let messagesRef = self.ref.child("messages") let uid = "UserId1" let status = "unread" let queryString = uid + "_" + status //results in a string UserId1_unread let ref = messagesRef.queryOrdered(byChild: "forUid_status").queryEqual(toValue: queryString) ref.observe(.value, with: { snapshot in if snapshot.exists() { let count = snapshot.childrenCount print("unread messages: \(count)") } else { print("no unread messages") } }) 

针对上述Firebase运行此代码导致

 unread messages: 1 

这也可能有助于加载未读消息,因为您不仅可以获得计数,而且只要为UserId1添加新的未读消息,将观察者添加到该节点也会通知应用程序