【发布时间】:2021-06-14 19:33:10
【问题描述】:
你好!
首先我有一个简单的问题。当事务失败时,它会以数据库的基本状态重新启动。我想知道,我们是每次在完成块中失败时输入还是仅在达到最大尝试次数时输入。
现在真正的问题:
在我的 iOS 应用程序中,当用户在“消息”表中发送消息时,我必须增加用户在数据库的“用户”表中发送的消息数。所以我决定使用事务来确保数据库保持一致。 代码如下:
private static func createNewTradeDb(_ content : String){
let now = DateFormatter()
now.dateStyle = .medium
now.timeStyle = .medium
now.locale = Locale(identifier: "FR-fr")
dbRef.runTransactionBlock ({ (currentData) -> TransactionResult in
let userId = Auth.auth().currentUser?.uid
if var dbInfo = currentData.value as? [String : Any] {
var message = dbInfo["Message"] as? [String : Any] ?? [:]
var userInfo = dbInfo["Users"] as? [String : Any] ?? [:]
var currentMessageInfo = messageInfo[userId!] as? [String : Any] ?? [:]
var currentUserInfo = userInfo[userId!] as? [String : Any] ?? [:]
currentMessageInfo["date"] = now.string(from: Date())
currentMessageInfo["content"] = content
currentUserInfo["messageCounter"] = self.messageCounter + 1
messageInfo[userId!] = currentMessageInfo
userInfo[userId!] = currentUserInfo
dbInfo["Message"] = MessageInfo
dbInfo["Users"] = userInfo
currentData.value = dbInfo
//We send a notification if the writing finished
let name = Notification.Name(rawValue: "writingMessageFinished")
let notification = Notification(name: name)
NotificationCenter.default.post(notification)
}
return TransactionResult.success(withValue: currentData)
}){
(error,commited,snapshot) in
if error != nil{
//We send a notification if the writing failed
let name = Notification.Name(rawValue: "writingMessageFailed")
let notification = Notification(name: name)
NotificationCenter.default.post(notification)
}
}
}
问题是当我从一个帐户发送消息时,我收到“权限被拒绝”。我的安全规则如下:
{
"rules": {
"Users": {
"$userId": {
".read": "auth != null && $userId === auth.uid",
".write": "auth != null && $userId === auth.uid",
},
},
"Message": {
"$userId": {
".read": "auth != null && $userId === auth.uid",
".write": "auth != null && $userId === auth.uid",
},
}
}
}
确实,因为我没有在一般“规则”中为数据库指定任何内容:我想这些行丢失了:
if var dbInfo = currentData.value as? [String : Any] {
var tradeInfo = dbInfo["Trade"] as? [String : Any] ?? [:]
var userInfo = dbInfo["Users"] as? [String : Any] ?? [:]
仅当我更改规则以允许读取或写入这些位置时,子路径 ($userId) 不能像文档中所述的那样具有更多限制性。所以我不能再强制用户只写入或读取他们的 id 字段。
我想知道如何安排在两个不同的表“用户”和“消息”上进行交易。
感谢您的关注:)
【问题讨论】:
标签: swift firebase-realtime-database transactions