【发布时间】:2017-02-28 17:39:27
【问题描述】:
我的数据结构如下:
restaurant_owners
|
|owner_id (a unique ID)
|
|restaurant_name
|email
restaurant_menus
|
|restaurant_name
|
|dish_type (drinks, appetizer, etc...)
|
|dish_id (a unique ID)
|
|name
|
|price
该应用程序的想法基本上是允许“restaurant_owners”登录并管理他们各自餐厅的菜单。但是我在使用以下代码时遇到问题:(请注意,在 viewDidLoad 中调用了 fetchDish 函数)
func fetchDish() {
var restaurantName: String?
let uid = FIRAuth.auth()?.currentUser?.uid
//first time referencing database
FIRDatabase.database().reference().child("owners").child(uid!).observeSingleEvent(of: .value, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject] {
DispatchQueue.main.async{
restaurantName = dictionary["name"] as? String
print(restaurantName!)
}
}
})
//second time referencing database
FIRDatabase.database().reference().child("restaurants").child(restaurantName!).child("appetizer").observe(.childAdded, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject] {
let dish = Dish()
dish.setValuesForKeys(dictionary)
self.dishes.append(dish)
DispatchQueue.main.async {
self.tableview.reloadData()
}
}
}, withCancel: nil)
}
我要做的是检索当前登录用户的餐厅名称并将其存储在变量“restaurantName”中。然后,当我第二次引用数据库时,我可以在 .child 中使用这个变量(例如:.child(restaurantName))。
但是,当我运行它时,我收到一条错误消息,指出 restaurantName(在数据库引用中)的值为零。我尝试放置一些断点,似乎第二个数据库引用的第一行是在第一个数据库引用“内”的任何内容之前操作的,所以基本上 restaurantName 在存储任何值之前被调用。
为什么会这样?我该如何解决这个问题?另外,如果我做错了,实现这一目标的最佳做法是什么?
NoSQL 对我来说非常陌生,我完全不知道应该如何设计我的数据结构。提前感谢您的帮助,如果您需要任何其他信息,请告诉我。
更新:
通过将我的数据结构更改为 Jay 的建议,问题得到了解决。以下代码对我有用:(稍微修改了杰的代码)
func fetchOwner() {
let uid = FIRAuth.auth()?.currentUser?.uid
let ownersRef = FIRDatabase.database().reference().child("owners")
ownersRef.child(uid!).observeSingleEvent(of: .value, with: { snapshot in
if let dict = snapshot.value as? [String: AnyObject] {
let restaurantID = dict["restaurantID"] as! String
self.fetchRestaurant(restaurantID: restaurantID)
}
}, withCancel: nil)
}
func fetchRestaurant(restaurantID: String) {
let restaurantsRef = FIRDatabase.database().reference().child("restaurants")
restaurantsRef.child(restaurantID).child("menu").observe(.childAdded, with: { snapshot in
if let dictionary = snapshot.value as? [String: AnyObject] {
let dish = Dish()
dish.setValuesForKeys(dictionary)
self.dishes.append(dish)
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}, withCancel: nil)
}
【问题讨论】:
-
请删除 DispatchQueue.main.async。不需要。
-
使用 DispatchQueue.main.async 是否有任何特定的负面影响?当我将 self.tableview.reloadData() 放入其中时,它显着加快了表格加载信息的时间。
-
在这个应用程序中,它不应该对性能产生任何明显的影响,因为在从服务器接收到 Firebase 数据并处理闭包中的代码之前,不会刷新 tableView。在这种情况下,您将在主串行队列上抛出一个异步任务,该任务将任务按顺序排列在其前面的任何内容之后。即不需要,因为 Firebase 函数已经是异步的。
标签: ios firebase swift3 firebase-realtime-database nosql