Ios 从firebase实时数据库获取并显示用户名

Ios 从firebase实时数据库获取并显示用户名,ios,firebase,swift3,firebase-realtime-database,Ios,Firebase,Swift3,Firebase Realtime Database,我试图从firebase实时数据库中获取用户名,并将其显示在我的TableViewCell标签中。我做错了什么?userShortname.text仍然为空。我只使用电子邮件/密码验证 这是我的密码 var ref: FIRDatabaseReference! var username: String = "" override func viewDidLoad() { super.viewDidLoad() ref = FIRDatabase.database().refe

我试图从firebase实时数据库中获取用户名,并将其显示在我的TableViewCell标签中。我做错了什么?userShortname.text仍然为空。我只使用电子邮件/密码验证 这是我的密码

var ref: FIRDatabaseReference!
var username: String = ""

override func viewDidLoad() {
    super.viewDidLoad()

    ref = FIRDatabase.database().reference()
    let userID = FIRAuth.auth()?.currentUser?.uid
    let profilePath = ref.child("users").child(userID!)
        profilePath.observeSingleEvent(of: .value, with: { (snapshot) in
            let snapValue = snapshot.value as? NSDictionary
            let snapUsername = snapValue?["username"] as? String ?? ""
            self.username = snapUsername
        })

}

// MARK: - Table view data source

override func numberOfSections(in tableView: UITableView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows
    return 1
}


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "userCell", for: indexPath) as! ProfileTableViewCell

    cell.userAvatar.layer.cornerRadius = 35.5
    cell.userAvatar.clipsToBounds = true
    cell.userShortname.text = self.username

    return cell
}

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: true)
}

在退出
obserseSingleEvent
闭包之前,添加一个
self.tableView.reloadData()
。例如:

profilePath.obserseSingleEvent(of: .value) { (snapshot) in
    ...
    self.username = snapUsername
    self.tableView.reloadData()
}

这将让您的
tableView
知道网络响应已经到达;)

在退出
obserseSingleEvent
闭包之前,添加一个
self.tableView.reloadData()
。例如:

profilePath.obserseSingleEvent(of: .value) { (snapshot) in
    ...
    self.username = snapUsername
    self.tableView.reloadData()
}

这将让您的
tableView
知道网络响应已经到达;)

1。Firebase调用是异步的

这意味着将创建一个单独的线程来处理分配给它的任务,主线程在继续执行下一个操作之前从不等待任务完成

2。iOS主线程

所有UI更新都是通过主线程完成的。切勿在此线程上运行耗时超过几分之一秒的冗长任务

Firebase执行完任务后,您需要将此信息传递回用户,因此需要进行UI更新。只要简单地编写
self.tableView.reloadData()
就可以一直工作,前提是Firebase的一切运行都很顺利;甚至他们也不能保证:)

如果Firebase查询挂起:

Blocks the main thread
       ----> Deem your app unresponsive
            --> If unresponsive for a couple seconds, the watchdog kills your app.
为了避免这种情况,一旦Firebase的线程执行完毕,并且您在内存中添加了新数据,您需要告诉主线程执行任何相关的UI更新

profilePath.obserseSingleEvent(of: .value) { (snapshot) in
    ...
    self.username = snapUsername

    DispatchQueue.main.async
    {
      self.tableView.reloadData()
    }
}

我建议您熟悉并阅读冗长任务操作的答案。

1。Firebase调用是异步的

这意味着将创建一个单独的线程来处理分配给它的任务,主线程在继续执行下一个操作之前从不等待任务完成

2。iOS主线程

所有UI更新都是通过主线程完成的。切勿在此线程上运行耗时超过几分之一秒的冗长任务

Firebase执行完任务后,您需要将此信息传递回用户,因此需要进行UI更新。只要简单地编写
self.tableView.reloadData()
就可以一直工作,前提是Firebase的一切运行都很顺利;甚至他们也不能保证:)

如果Firebase查询挂起:

Blocks the main thread
       ----> Deem your app unresponsive
            --> If unresponsive for a couple seconds, the watchdog kills your app.
为了避免这种情况,一旦Firebase的线程执行完毕,并且您在内存中添加了新数据,您需要告诉主线程执行任何相关的UI更新

profilePath.obserseSingleEvent(of: .value) { (snapshot) in
    ...
    self.username = snapUsername

    DispatchQueue.main.async
    {
      self.tableView.reloadData()
    }
}

我建议您熟悉并阅读冗长任务操作的答案。

Hey@Pselok,请将相关代码复制到问题正文(而不是图像链接)。谢谢兄弟!嘿@Pselok,请将相关代码复制到问题正文(而不是作为图像链接)。谢谢兄弟!非常感谢你!我在退出ObserveSinglevent后尝试添加它非常感谢!在退出ObserveSinglevent之后,我试图添加它,伙计,欢迎您。把两个回答中的一个标记为你的最终答案并进行投票,以结束你的问题。快乐编码!:)顺便说一下,Firebase完成块总是在主队列上调用,因此您根本不需要将这些调用包装在
DispatchQueue.main
中;)欢迎你,伙计。把两个回答中的一个标记为你的最终答案并进行投票,以结束你的问题。快乐编码!:)顺便说一下,Firebase完成块总是在主队列上调用,因此您根本不需要将这些调用包装在
DispatchQueue.main
中;)