2016-06-07 38 views
1

在此应用程序中,每个用户都有一个“投票”计数器,但只有当同一个用户投票时,当另一个用户试图在该引用中执行FIRTransaction时,它才会起作用,它返回nil 。规则设置给任何用户。
当我需要user2更新user1“votes”值时,它不会读取该键值来执行事务块,因此它返回nil。Firebase 3无法修改其他用户创建的数据

votesCountRef = ref.child("user1").child("votes") 
votesCountRef.runTransactionBlock({ (currentData) -> FIRTransactionResult in 
      let value = currentData.value! as! Int 
      currentData.value = value + 1 
      return FIRTransactionResult.successWithValue(currentData) 
     }) 

结果:

得票实际值:可选() 无法投类型的值 'NSNull'(0x110684600)到 '的NSNumber'(0x10fce92a0)。

但是,当原始用户运行这个,它工作成功。

的Json树USER1:

{ 
    "userUID" : "user1", 
    "votes" : 2 
} 

数据库规则:

{ 
    "rules": { 
    ".read": "auth != null", 
    ".write": "auth != null" 
    } 
} 

感谢@Frank我能管理这样的:

ownerReceivedVotesCountRef.runTransactionBlock({ (currentData) -> FIRTransactionResult in 

    let value = currentData.value as? Int ?? 0 
    currentData.value! = (value as Int) + 1 
    return FIRTransactionResult.successWithValue(currentData) 
}) 

回答

1

交易处理是最初运行与客户对当前价值的最佳猜测。通常这将是nil,所以你的代码必须处理。

Firebase documentation

注:由于runTransactionBlock:andCompletionBlock:被多次调用,它必须能够处理nil数据。即使远程数据库中存在现有数据,在事务功能运行时,它也可能不会在本地缓存,导致初始值为nil

像这样的东西应该为你的情况下工作:

let value = currentData.value as? Int ?? 0 
+0

谢谢,我试图把格式化代码的解决方案:'ownerReceivedVotesCountRef.runTransactionBlock({(CURRENTDATA) - > FIRTransactionResult在 print(“\(self.currentPost!.owner)Received votes actual value:\(currentData.value)”) let value = currentData.value as?Int ?? 0 currentData.value!=(value as Int)+ 1 return FIRTransactionResult.successWithValue(currentData) })' –