我的数据结构是类似以下内容:检索从火力地堡数据,而在另一个火力地堡数据库参考使用它
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”登录和管理的菜单他们各自的餐厅。但是我有下面的代码的问题:(注意fetchDish函数被调用viewDidLoad中)
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对我来说是非常新的,我完全不知道应该如何设计我的数据结构。感谢您的帮助,如果您需要其他信息,请告诉我。
UPDATE:
问题可通过改变我的数据结构是什么周杰伦曾建议解决。下面的代码是对我工作:(修改周杰伦的代码位)
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。这不是必需的。 – Jay
使用DispatchQueue.main.async是否有任何特定的负面影响?当我将self.tableview.reloadData()放入其中时,它明显加快了表加载信息的时间。 – JustTro11
在这个应用程序中,它不应该有任何明显的性能差异,因为在从服务器收到Firebase数据并处理闭包中的代码之前,tableView不会被刷新。在这种情况下,您会在主串行队列上抛出一个异步任务,这会使任务按顺序排在前面。即不需要,因为Firebase功能已经是异步的。 – Jay