Firebase 在函数返回后检索数据
Firebase retrieves data after the function have returned
我是 swift 和 firebase 的新手,我需要一些帮助。我写了一个 swift2 函数,可以从 firebase 检索数据,但它没有用。
代码如下:
func fetchUidWithEmail (email: String) -> String {
var uid = ""
ref.child("userList").queryOrderedByChild("email").queryEqualToValue(email).observeEventType(.Value, withBlock: { (snapshot) in
if let snapshots = snapshot.children.allObjects as? [FIRDataSnapshot] {
for snap in snapshots {
uid = snap.key
}
}
})
return uid
}
我试图在 for 块中打印 snap,它出现在 uid 值 returned 之后。所以我总是从这个函数中得到一个空字符串 return 。有什么方法可以解决这个问题吗?非常感谢。
Firebase 数据库中的数据是异步读取的。这意味着您的代码执行顺序可能不是您所期望的。最简单的方法是添加一些打印语句:
func fetchUidWithEmail (email: String) -> String {
print("Before starting query")
ref.child("userList").queryOrderedByChild("email").queryEqualToValue(email).observeEventType(.Value, withBlock: { (snapshot) in
print("In query callback block")
})
print("After starting query")
}
当你运行这段代码时,输出是:
Before starting query
After starting query
In query callback block
这可能不是您所期望的。但这确实解释了为什么 returning uid 不起作用:当你 return uid 时,它还没有从 Firebase 加载。
解决这个问题的方法是改变你思考问题的方式。与其说“首先获取 uid,然后用 uid 做点什么”,不如说“只要我们得到 uid,就用它做点什么”。
最简单的方法是将需要 uid 的代码写入加载数据的函数中:
func fetchUidWithEmail (email: String) -> String {
ref.child("userList").queryOrderedByChild("email").queryEqualToValue(email).observeEventType(.Value, withBlock: { (snapshot) in
if let snapshots = snapshot.children.allObjects as? [FIRDataSnapshot] {
for snap in snapshots {
print(snap.key)
// TODO: do anything you want with the uid here
}
}
})
}
虽然这可行,但这意味着您可能有很多地方可以通过电子邮件加载 uid。如果您可以将需要 uid 的代码传递给您的函数,它会更易于重用:
func fetchUidWithEmail (email: String, withBlock: String -> Void) -> Void {
ref.child("userList").queryOrderedByChild("email").queryEqualToValue(email).observeEventType(.Value, withBlock: { (snapshot) in
if let snapshots = snapshot.children.allObjects as? [FIRDataSnapshot] {
for snap in snapshots {
withBlock(snap.key)
}
}
})
}
然后你可以调用它:
fetchUidWithEmail("frank.vanpuffelen@gmail.com") { (uid) in
print(uid)
}
这正是 Firebase 数据库客户端本身的工作方式:当您添加观察者时,您会传入一个 callback/block.
我是 swift 和 firebase 的新手,我需要一些帮助。我写了一个 swift2 函数,可以从 firebase 检索数据,但它没有用。
代码如下:
func fetchUidWithEmail (email: String) -> String {
var uid = ""
ref.child("userList").queryOrderedByChild("email").queryEqualToValue(email).observeEventType(.Value, withBlock: { (snapshot) in
if let snapshots = snapshot.children.allObjects as? [FIRDataSnapshot] {
for snap in snapshots {
uid = snap.key
}
}
})
return uid
}
我试图在 for 块中打印 snap,它出现在 uid 值 returned 之后。所以我总是从这个函数中得到一个空字符串 return 。有什么方法可以解决这个问题吗?非常感谢。
Firebase 数据库中的数据是异步读取的。这意味着您的代码执行顺序可能不是您所期望的。最简单的方法是添加一些打印语句:
func fetchUidWithEmail (email: String) -> String {
print("Before starting query")
ref.child("userList").queryOrderedByChild("email").queryEqualToValue(email).observeEventType(.Value, withBlock: { (snapshot) in
print("In query callback block")
})
print("After starting query")
}
当你运行这段代码时,输出是:
Before starting query
After starting query
In query callback block
这可能不是您所期望的。但这确实解释了为什么 returning uid 不起作用:当你 return uid 时,它还没有从 Firebase 加载。
解决这个问题的方法是改变你思考问题的方式。与其说“首先获取 uid,然后用 uid 做点什么”,不如说“只要我们得到 uid,就用它做点什么”。
最简单的方法是将需要 uid 的代码写入加载数据的函数中:
func fetchUidWithEmail (email: String) -> String {
ref.child("userList").queryOrderedByChild("email").queryEqualToValue(email).observeEventType(.Value, withBlock: { (snapshot) in
if let snapshots = snapshot.children.allObjects as? [FIRDataSnapshot] {
for snap in snapshots {
print(snap.key)
// TODO: do anything you want with the uid here
}
}
})
}
虽然这可行,但这意味着您可能有很多地方可以通过电子邮件加载 uid。如果您可以将需要 uid 的代码传递给您的函数,它会更易于重用:
func fetchUidWithEmail (email: String, withBlock: String -> Void) -> Void {
ref.child("userList").queryOrderedByChild("email").queryEqualToValue(email).observeEventType(.Value, withBlock: { (snapshot) in
if let snapshots = snapshot.children.allObjects as? [FIRDataSnapshot] {
for snap in snapshots {
withBlock(snap.key)
}
}
})
}
然后你可以调用它:
fetchUidWithEmail("frank.vanpuffelen@gmail.com") { (uid) in
print(uid)
}
这正是 Firebase 数据库客户端本身的工作方式:当您添加观察者时,您会传入一个 callback/block.