如何使用firebase实时数据库ios增加特定节点中的值
Posted
技术标签:
【中文标题】如何使用firebase实时数据库ios增加特定节点中的值【英文标题】:How to increment the value in specific node with firebase realtime database ios 【发布时间】:2018-10-28 04:11:00 【问题描述】:我正在使用聊天应用程序,我想维护接收方的未读计数。我在控制台中的 json 结构看起来像
user_history | |--> user_a_uuid |-> last_msg |-> last_msg_timestamp |-> unread_count
这个问题的范围是,如何增加unread_count
的值。在递增之前,我将user_a_uuid
和节点user_history
和unread_count
作为常数。所以我尝试如下
dbRef.child("user_history")
.child(user_a_uuid)
.child("unread_count")
.runTransactionBlock (unreadCount) -> TransactionResult in
var value = unreadCount.value as? Int
if value == nil
value = 0
unreadCount.value = value! + 1
return TransactionResult.success(withValue: unreadCount)
实际上,我从here 借用了这个解决方案。我也尝试关注doc。但问题是,我不想像在文档中那样在根节点上运行事务。我只想在unread_count
文档上运行事务。
我面临的问题:
在尝试此代码后,我面临的问题是,unread_count
节点被立即删除,而我在完成块内返回TransactionResult
,它添加了unread_count
。问题是由于unread_count
被删除,该值没有增加。它总是停留在1
。
提前致谢。
【问题讨论】:
请考虑发表评论,尚不清楚哪一部分。 【参考方案1】:您似乎希望增加存储在节点中的计数器而不影响节点中的其他项目。根据问题中的信息,由于计数存储在代码中,因此在此用例中似乎不需要使用事务块。
在递增之前,我有 user_a_uuid 和节点 user_history & unread_count 为常量
我相信这意味着您将 unread_count 存储在代码中的 变量 中,因此如果这是正确的,它只需要在代码中递增并写入节点。
从重复结构开始:
user_history
uid_0
last_msg: "some message"
last_msg_timestamp: "20181028075700"
unread_count: 2
现在我们添加了另一条消息。 var 需要递增,然后 Firebase 中的相应节点需要使用新值进行更新。这是执行此操作的代码:
func updateMsgCount()
self.unread_count += 1 //this is a class var or however it's stored in code
let unreadCountRef = self.ref.child("user_history").child("uid_0").child("unread_count")
unreadCountRef.setValue(self.unread_count)
但是,假设 unread_count 未存储在代码中,而仅存储在 Firebase 中。这是在 unread_count 节点中读取的代码,增加计数并将其存储回 Firebase。
func updateCount()
let unreadCountRef = self.ref.child("user_history").child("uid_0").child("unread_count")
unreadCountRef.observeSingleEvent(of: .value, with: snapshot in
var currentCount = snapshot.value as? Int ?? 0
currentCount += 1
unreadCountRef.setValue(currentCount)
)
如果你真的需要一个事务块,这里有一个来完成同样的事情
func updateCountTransactionStyle()
let unreadCountRef = self.ref.child("user_history").child("uid_0").child("unread_count")
unreadCountRef.runTransactionBlock( (currentData: MutableData) -> TransactionResult in
var currentCount = currentData.value as? Int ?? 0
currentCount += 1
currentData.value = currentCount
return TransactionResult.success(withValue: currentData)
)
【讨论】:
感谢您的努力。实际上我没有在变量中维护unread_count
,我只需要在接收方读取它并显示为徽章。原因是,这里使用的事务是用户可以从多个设备登录,虽然从多个设备同时发送消息是不切实际的,但我添加了这个以防发生此类事件。您分享的最后一个块实际上与我用较短版本提出的问题相同。
我在我的代码中发现了错误,其中设置了last_message
、last_msg_timestamp
和unread_count
的整个字典。整个字典的这种写作删除了unread_count
。解决方案是遍历字典allKeys
中的每个键,并在节点上一一写入。
@RatulSharker 很高兴您发现了这个问题!我希望我的回答有所帮助,因为我认为这是您问题的解决方案,即使有一个单独的问题。如果它帮助或提供了方向,请接受它,以便它可以帮助他人。我不认为遍历节点是最好的解决方案。从我的两个示例中可以看出,您应该能够只读取 unread_count、递增并将其写回而不擦除其他值。
我必须遍历字典的情况,因为发送方设置此值,接收方意味着在接收方进入消息详细信息视图时将其设置为零。在您的建议中,last_message
、last_message_timestamp
和 unread_count
在将字典写入该节点之前需要先读取。这似乎是更多的任务,读写unread_count
可能会在发送方递增它而接收方将其设置为零时产生错误,因此不能让递增操作在事务之外进行。以上是关于如何使用firebase实时数据库ios增加特定节点中的值的主要内容,如果未能解决你的问题,请参考以下文章
将新数据添加到特定子项时如何使用 Cloud Functions 将数据写入 Firebase 实时数据库
如何从 firebase 实时数据库中获取数据并更改一个文本字段以表示该特定记录?