我正在尝试编写聊天应用。
我想计算未查看的消息数(看不见)。
我的数据库如下所示:
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)
}
答案 0 :(得分:0)
根据@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中存储计数器的想法是因为它可以在应用程序的任何地方访问,并且可以直接显示在任何标签或按钮中。
答案 1 :(得分:0)
我们可以利用复合值来轻松处理这个问题。
对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添加新的未读消息,向该节点添加观察者也会通知应用