Firebase Observe在执行以下命令后调用

时间:2017-11-21 17:27:59

标签: swift firebase firebase-realtime-database

我正在尝试从Firebase加载用户名,而该用户名应该在Object中设置。但是,在已经设置名称后,将调用Firebase Observe Command。有什么问题,我该如何解决?

let ref = Database.database().reference().child("Users").child(currentMessage.senderId).child("name")

ref.observeSingleEvent(of: .value, with: { (snapshot) in

    // This is supposed to be called first
    self.username = snapshot.value as! String
    print(self.username)
})

// This somehow gets called first
let nameModel = NameModel(name: self.username, uid: *some UID*)
decoratedItems.append(DecoratedChatItem(chatItem: nameModel, decorationAttributes: nil))

1 个答案:

答案 0 :(得分:1)

Firebase异步加载其数据库中的数据。这意味着代码的执行顺序与您期望的顺序不同。最简单的方法是使用一些日志语句:

let ref = Database.database().reference().child("Users").child(currentMessage.senderId).child("name")
print("Before attaching observer")
ref.observeSingleEvent(of: .value, with: { (snapshot) in
    print("In completion handler")
})
print("After attaching observer")

与您的预期不同,此代码打印:

  

在加入观察者之前

     

附上观察员后

     

在完成处理程序

这是因为从Firebase(或任何其他Web服务)加载数据可能需要一些时间。如果代码等待,则会阻止用户与您的应用程序进行交互。因此,Firebase会在后台加载数据,并让您的代码继续运行。然后,当数据可用时,它会调用您的完成处理程序。

习惯这种模式的最简单方法是重新构建您的问题。而不是说“首先加载数据,然后将其添加到列表中”,将问题框架为“开始加载数据。加载数据时,将其添加到列表中”。

在代码中,这意味着您将需要数据的任何代码移动到完成处理程序中:

let ref = Database.database().reference().child("Users").child(currentMessage.senderId).child("name")    
ref.observeSingleEvent(of: .value, with: { (snapshot) in    
    self.username = snapshot.value as! String
    let nameModel = NameModel(name: self.username, uid: *some UID*)
    decoratedItems.append(DecoratedChatItem(chatItem: nameModel, decorationAttributes: nil))
})

有关此主题的更多问题,请参阅: