Reputation: 133
I am currently trying to access some book data that was put into my database under a random child ID. I've been scouring other questions, but the farthest I've gotten is being able to access the ID within a closure. I can't figure out how to properly set up a completion handler to extract the ID.
Also, I don't know if there's a much easier way to be going about this?
Here's the data I'm trying to access: Firebase data
And here's my current code that needs a completion handler, I think?
func getChildID(department: String, course: String) {
let parentRef = myDatabase.child("departments").child(department).child(course)
parentRef.observeSingleEvent(of: .value) { (courseSnapshot) in
if let data = courseSnapshot.value as? [String:String] {
for value in data {
let isbn = value.value
if isbn != "ISBN" {
myDatabase.child("listings").child("\(isbn)").observeSingleEvent(of: .value, with: { (snapshot) in
let dictionary = snapshot.value as! NSDictionary
for key in dictionary.keyEnumerator() {
let myKey = key as! String
return
}
})
}
}
}
}
}
Upvotes: 2
Views: 245
Reputation: 35667
Here we go. An answer to the question. However, and I mentioned in my comment to the question, the structure could be improved. However, there may be more children under each listing child so this answer handles it.
This just print's each authors name but it shows how to get to it so the answer should be expanded for the other child nodes.
let listingsRef = self.ref.child("listings")
listingsRef.observeSingleEvent(of: .value, with: { snapshot in
for child in snapshot.children {
let autoIdSnap = child as! DataSnapshot
for autoChild in autoIdSnap.children {
let childSnap = autoChild as! DataSnapshot
let dict = childSnap.value as! [String: Any]
let author = dict["author"] as! String
print(author)
}
}
})
Oh, and a better structure may be
listings
childByAutoId
author: "Some author"
listing: 9780184888
childByAutoId
author: "Another author"
listing: 9799292598
Edit: If there will only ever be one and only one childByAutoId under each listing, you can eliminate the loop in the above and do this
let listingsRef = self.ref.child("listings")
listingsRef.observeSingleEvent(of: .value, with: { snapshot in
for child in snapshot.children {
let autoIdSnap = child as! DataSnapshot //each listing
let childDict = autoIdSnap.value as! [String: Any] //a dict of items within the listing
let firstKey = childDict.keys.first! //the key to the first item
let valuesDict = childDict[firstKey] as! [String: Any] //the values for that key
let author = valuesDict["author"] as! String //the author value
print(author)
}
})
Upvotes: 2
Reputation: 1292
You can observe changes in the last object before the childByAutoId(), in this case it would be "listings", and then create a model out of it.
override func viewDidLoad() {
super.viewDidLoad()
Auth.auth().signInAnonymously() { (user, error) in
if error == nil{
print("sign in successful")
}
}
let query = myDatabase.child("listings")
query?.removeAllObservers()
query?.observe(.value, with: { snapshot in
if snapshot.exists() {
let booksSnapshot = Books(snap: snapshot)
for children in booksSnapshot.books{
let childByAutoId = children.value as! NSDictionary
for books in childByAutoId{
let key = books.value as! NSDictionary
let book: Books = Books(fromJson: JSON())
book.author = key["author"] as! String
book.title = key["title"] as! String
book.price = key["price"] as! Int
print(book.price)
}
}
}
})
}
//Model //Note: you will have to install the 'SwiftyJSON' to create this model
import Foundation
import SwiftyJSON
import Firebase
class Books : NSObject{
var author : String!
var title : String!
var price : Int! // you can add more variables later
var books : [String: AnyObject]!
init(fromJson json: JSON!){
if json.isEmpty{
return
}
author = json["author"].stringValue
title = json["title"].stringValue
price = json["price"].intValue
}
/**
* Instantiate the instance using the passed json values to set the properties values
*/
init(snap: DataSnapshot){
let json = snap.value as! NSDictionary
books = json as! [String: AnyObject]
}
}
Upvotes: 1