【问题标题】:Firebase Observe called after following command在执行以下命令后调用 Firebase Observe
【发布时间】:2017-11-21 17:27:59
【问题描述】:

我正在尝试从 Firebase 加载用户名,该用户名应该设置在对象中。但是在名称已经设置之后,就会调用 Firebase Observe 命令。有什么问题,我该如何解决?

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

【问题讨论】:

  • 在等待执行这些行时,它会在关闭后执行。

标签: swift firebase firebase-realtime-database


【解决方案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(或任何其他网络服务)加载数据可能需要一些时间。如果代码会等待,它将阻止您的用户与您的应用程序交互。因此,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))
})

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-05
    相关资源
    最近更新 更多