我的數據結構是類似以下內容:檢索從火力地堡數據,而在另一個火力地堡數據庫參考使用它
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