我成功地从Firebase获取了数据,但是我无法将其推入数组以供使用。我的数据库如下:
users
-Wc1EtcYzZSMPCtWZ8wRb8RzNXqg2
-email : "mike@gmail.com"
-lists
-LJiezOzfDrqmd-hnoH-
-owner: Wc1EtcYzZSMPCtWZ8wRb8RzNXqg2
-LJif-UgPgbdGSHYgjY6
-owner: Wc1EtcYzZSMPCtWZ8wRb8RzNXqg2
shopping-lists
-LJh6sdBJtBCM7DwxPRy
-name: "weekly shopping"
-owner: "mike@gmail.com"
登录后我有一个主页,该主页在表上显示现有的购物清单(如果存在)。在viewDidLoad()上,我从用户那里获得购物清单ID,并使用这些ID作为参考来从购物清单中获取详细信息。
但是,我无法将这些数据保存到数组中,因为关闭后它们将被删除。我怎样才能做到这一点?
override func viewDidLoad() {
super.viewDidLoad()
SVProgressHUD.show()
tableView.allowsMultipleSelectionDuringEditing = false
// Sets user variable - must have
Auth.auth().addStateDidChangeListener { auth, user in
guard let user = user else { return }
self.user = User(authData: user)
// If new user, write into Firebase
self.usersRef.observeSingleEvent(of: .value, with: { snapshot in
if !snapshot.hasChild(self.user.uid) {
self.usersRef.child(user.uid).setValue(["email": user.email!])
}
})
// Get shopping lists data from "users/lists"
self.usersRef.child(user.uid).child("lists").observe(.value, with: { snapshot in
// Get list IDs
if snapshot.exists() {
if let result = snapshot.children.allObjects as? [DataSnapshot] {
for child in result {
self.listNames.append(child.key)
}
}
}
// Use list IDs - to get details
for item in self.listNames {
let itemRef = self.shoppingListsRef.child(item)
itemRef.observeSingleEvent(of: .childAdded, with: { (snapshot) in
if let value = snapshot.value as? [String: Any] {
let name = value["name"] as? String ?? ""
let owner = value["owner"] as? String ?? ""
let shoppingList = ShoppingList(name: name, owner: owner)
self.items.append(shoppingList)
}
})
}
})
self.tableView.reloadData()
SVProgressHUD.dismiss()
}
}
答案 0 :(得分:1)
(这个问题有点不清楚,所以这个答案的几个部分涵盖了所有可能。这是Swift 4,Firebase 4/5)
您实际上不需要在这里查询,因为您知道它们的键想要哪个节点,并且将始终按照listNames数组的顺序对其进行读取。假设self.listNames是您要读取的键。
for item in listNames {
let itemRef = shoppingListsRef.child(item)
itemRef.observe(.value, with: { (snapshot) in
if let value = snapshot.value as? [String: Any] {
let name = value["name"] as? String ?? ""
let owner = value["owner"] as? String ?? ""
print(name, owner)
}
})
}
通常,查询是在节点内搜索某些内容时使用的-例如,如果您正在寻找一个包含“每周购物”子名称的节点。除此之外,坚持直接读取节点是因为它更快,开销更少。继续阅读...
我还删除了较旧的NSDictionary,并使用了Swift [String:Any]并修改了错误检查
但是,真正的问题是读取具有.value的节点。请记住,.value会读取节点的所有子级,然后需要对其进行迭代以获取每个单独的DataSnapshot。另外,.observe在节点上让观察者通知应用程序更改,我认为您不希望这样做。因此,这将回答发布的问题(并且需要更好的错误检查)
for item in listNames {
let queryRef = shoppingListsRef
.queryOrdered(byChild: "name")
.queryEqual(toValue: item)
queryRef.observe(.value, with: { (snapshot) in
for child in snapshot.children { //even though there is only 1 child
let snap = child as! DataSnapshot
let dict = snap.value as! [String: Any]
let name = dict["name"] as? String ?? ""
let owner = dict["owner"] as? String ?? ""
print(name, owner)
}
})
}
答案...
这可能是您想要的更多...
for item in listNames {
let queryRef = shoppingListsRef
.queryOrdered(byChild: "name")
.queryEqual(toValue: item)
queryRef.observeSingleEvent(of: .childAdded, with: { snapshot in
let dict = snapshot.value as! [String: Any]
let name = dict["name"] as? String ?? ""
let owner = dict["owner"] as? String ?? ""
print(name, owner)
})
}
请注意.childAdded而不是.value,该快照将快照作为单个DataSnapshot呈现,并且不需要进行迭代,而.observeSingleEvent不会将观察者附加到每个节点。
编辑
根据其他信息,最好也将结构更改为此
shopping-lists
-LJh6sdBJtBCM7DwxPRy
-name: "weekly shopping"
-uid: "Wc1EtcYzZSMPCtWZ8wRb8RzNXqg2"
,然后当用户登录时,只需在购物清单节点中查询自己的任何uid。