Firebase事务块无法读取正确attend count,返回值异常求助
解决Firebase事务块无法获取正确
attend:count值的问题 看起来你的事务块始终读取到0而非数据库中实际的2,我来帮你排查几个核心原因并给出解决方案:
1. 首先检查数据库安全规则
这是最常见的问题根源:如果你的Firebase数据库规则没有授予读取events/{key}/attend:count的权限,事务将无法从服务器获取当前值,只能使用默认的0。
确保你的规则允许授权用户读取该节点,比如:
{ "rules": { "events": { "$eventId": { "attend:count": { ".read": "auth != null", // 允许已登录用户读取 ".write": "auth != null" // 允许已登录用户修改 } } } } }
2. 验证事件Key的正确性
打印event?.key的值,确认它和数据库中目标事件的节点Key(比如你示例中的ABP)完全一致。如果Key不匹配,事务会指向一个不存在的节点,mutableData.value自然为nil,最终currentCount被设为0。
3. 确认attend:count的存储类型
检查数据库中attend:count的实际类型:必须是整数而非字符串。如果它被误存为字符串(比如"2"),mutableData.value as? Int会返回nil,导致currentCount使用默认值0。
4. 添加日志排查细节
修改你的事务代码,增加详细日志,以便追踪每次事务执行的状态和数值:
static func create(for event: Event?, success: @escaping (Bool) -> Void) { guard let key = event?.key else { print("Error: Event key is nil") return success(false) } guard let uid = Auth.auth().currentUser?.uid else{ print("Error: User not logged in") return success(false) } let attendData = ["Attending/\(key)/\(uid)" : true, "users/\(uid)/Attending/\(key)" : true] let ref = Database.database().reference() ref.updateChildValues(attendData) { (error, _) in if let error = error { assertionFailure(error.localizedDescription) return success(false) } let attendCountRef = Database.database().reference().child("events").child(key).child("attend:count") attendCountRef.runTransactionBlock({ (mutableData) -> TransactionResult in // 增加日志查看当前值和类型 print("Transaction received value: \(mutableData.value)") print("Value type: \(type(of: mutableData.value))") let currentCount = mutableData.value as? Int ?? 0 print("Calculated current count: \(currentCount)") mutableData.value = currentCount + 1 return TransactionResult.success(withValue: mutableData) }, andCompletionBlock: { (error, committed, snapshot) in if let error = error { assertionFailure(error.localizedDescription) success(false) } else { print("Transaction committed: \(committed)") if let finalCount = snapshot?.value as? Int { print("Final attend count: \(finalCount)") } success(true) } }) } }
通过这些日志,你可以清楚看到事务是否读取到了正确的服务器值,以及类型转换是否正常。
额外优化建议
如果你的业务逻辑要求“记录用户报名”和“更新参与人数”必须原子性完成,可以考虑将这两个操作合并到一个事务中(不过当前分开的写法只要权限和路径正确,也能保证最终一致性)。
内容的提问来源于stack exchange,提问作者Ron Baker
相关产品推荐
相关产品推荐

