无法使用Firebase观察方法通过完成处理程序或任何其他方式传递完成的数组

时间:2018-09-22 16:11:56

标签: swift firebase firebase-realtime-database

当我尝试使用完成处理程序通过observe方法从Firebase数据库传递数据数组时,它仅传递数据库中的第一项(或者,当我尝试其他方法时则根本不传递)。我发现可以传递Firebase数据库中所有数据的数组的唯一方法是使用计时器,这是较差的做法。如何在Firebase数据库中传递完整的数据数组?

这是我的代码:

func loadHighScore(completionHandler:@escaping (_ scoresArray: [User]?)->()) {
    ref.child("Scores").observe(.childAdded, with: { (snapshot) in
        var scoresArray:[User] = []
        let dictionary = snapshot.value as? [String: AnyObject] ?? [:]
        let username = dictionary["Username"] as? String ?? ""
        let score = dictionary["High Score"] as? Int ?? 0
        let user = User(username: username, highScore: score)
        scoresArray.append(user)
        completionHandler(scoresArray)
    }, withCancel: {(err) in
        print("Error downloading profile: \(err)")
        completionHandler(nil)
    })
}

我这样称呼这个函数:

Firebase.sharedInstance.loadHighScore() { users in
    guard let users = users else { return }
    print("users: \(users)")
    self.sortedUsers = users.sorted {
        $0.highScore > $1.highScore
    }
    self.tableView.reloadData()
}

控制台显示一次正在打印一个用户,而不是一系列用户。表格视图仅显示一个用户,而不显示所有用户。当我尝试将for in循环与在for in循环外调用的完成处理程序一起使用时,出现关于如何不能使用for in循环的错误。

我该如何使用计时器来将完整的数组传递给调用我的观察Firebase函数的函数?

1 个答案:

答案 0 :(得分:0)

似乎您仅在快照上访问一个用户,因此请在下面尝试以下代码

 func loadHighScore(completionHandler:@escaping (_ scoresArray: [User]?)->()) {
        ref.child("Scores").observe(.value, with: { (snapshot) in
            var scoresArray:[User] = []
            for userSnap in snapshot.children {
                 guard let userSnapshot = userSnap as? FIRDataSnapshot else { 
                     return completion(scoresArray) // this will be empty array
                 }
                 let dictionary = userSnapshot.value as? [String: AnyObject] ?? [:]
                 let username = dictionary["Username"] as? String ?? ""
                 let score = dictionary["High Score"] as? Int ?? 0
                 let user = User(username: username, highScore: score)
                 scoresArray.append(user)
            }
            completionHandler(scoresArray)
        }, withCancel: {(err) in
            print("Error downloading profile: \(err)")
            completionHandler(nil)
        })
    }