Firebase 3无法修改其他用户创建的数据

时间:2022-03-14 08:47:03

In this application, each user has a counter for "votes" but it only works when the same user votes, when another user tries to do a FIRTransaction in that reference it returns nil. The rules are set to any user.
When I need that user2 updates the user1 "votes" value it doesn't reads that key value to perform the transaction block, so it returns nil.

在这个应用程序中,每个用户都有一个“投票”计数器,但只有当同一个用户投票时才有效,当另一个用户试图在该参考中进行FIRTransaction时,它返回nil。规则设置为任何用户。当我需要user2更新user1“votes”值时,它不会读取该键值来执行事务块,因此它返回nil。

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)
        })

result:

Received votes actual value: Optional() Could not cast value of type 'NSNull' (0x110684600) to 'NSNumber' (0x10fce92a0).

收到的投票实际值:可选()无法将类型'NSNull'(0x110684600)的值转换为'NSNumber'(0x10fce92a0)。

But when original user runs this it works successfully.

但是当原始用户运行它时,它可以成功运行。

Json tree for user1:

user1的Json树:

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

Database rules:

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

Thanks to @Frank I could manage it like this:

感谢@Frank,我可以像这样管理它:

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

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

1 个解决方案

#1


1  

A transaction handler is initially run with the client's best guess fo rthe current value. Quite often that will be nil, so your code has to handle that.

事务处理程序最初运行时客户端的最佳猜测是当前值。通常这将是零,所以你的代码必须处理它。

From the Firebase documentation:

从Firebase文档:

Note: Because runTransactionBlock:andCompletionBlock: is called multiple times, it must be able to handle nil data. Even if there is existing data in your remote database, it may not be locally cached when the transaction function is run, resulting in nil for the initial value.

注意:因为runTransactionBlock:andCompletionBlock:被多次调用,所以它必须能够处理nil数据。即使远程数据库中存在现有数据,在运行事务函数时也可能无法在本地缓存,导致初始值为nil。

Something like this should work for your case:

这样的事情应该适用于你的情况:

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

#1


1  

A transaction handler is initially run with the client's best guess fo rthe current value. Quite often that will be nil, so your code has to handle that.

事务处理程序最初运行时客户端的最佳猜测是当前值。通常这将是零,所以你的代码必须处理它。

From the Firebase documentation:

从Firebase文档:

Note: Because runTransactionBlock:andCompletionBlock: is called multiple times, it must be able to handle nil data. Even if there is existing data in your remote database, it may not be locally cached when the transaction function is run, resulting in nil for the initial value.

注意:因为runTransactionBlock:andCompletionBlock:被多次调用,所以它必须能够处理nil数据。即使远程数据库中存在现有数据,在运行事务函数时也可能无法在本地缓存,导致初始值为nil。

Something like this should work for your case:

这样的事情应该适用于你的情况:

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