【问题标题】:How to combine transaction and security rules on Firebase?如何在 Firebase 上结合交易和安全规则?
【发布时间】: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


    【解决方案1】:

    事务失败时,以数据库的基本状态重新启动。我想知道,我们是每次在完成块中失败时输入还是仅在达到最大尝试次数时输入。

    事务处理程序的完成块仅在事务完成后被调用,因此它只会被调用一次。在重试的情况下,只会多次调用第一个块。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-16
      • 2016-03-12
      • 2018-09-21
      • 2021-04-09
      • 2020-02-02
      • 2016-06-27
      • 1970-01-01
      相关资源
      最近更新 更多