I'm getting this error on the line let itemToAdd = snapshot.childSnapshot(forPath: "Shopa function that retrieves data from Firebase.
the output of the console in Could not cast value of type 'NSNull' (0x1118c8de0) to 'NSString' (0x10dda45d8)..
What I'm trying to do is to filter database ordering by one value
opening Timeand than get another value Shop Namefrom the returned entries in the snapshot.
here's the function:
func filterOpenShops(enterDoStuff: @escaping (Bool) -> ()) {
ref = Database.database().reference().child("Continent").child("Europe").child("Country").child("Italy").child("Region").child("Emilia-Romagna").child("City").child("Bologna").child("Shops").child("Shops Opening Times")
let query = ref?.queryOrdered(byChild: "Opening Time").queryStarting(atValue: openingTimeQueryStart).queryEnding(atValue: openingTimeQueryEnd)
query?.observe(.value, with: { (snapshot) in
for childSnapshot in snapshot.children {
// new modification
if childSnapshot is DataSnapshot {
let itemToAdd = snapshot.childSnapshot(forPath: "Shop Name").value as! String // gets the open shop from snapshot
self.availableShopsArray.append(itemToAdd)
print(snapshot.children)
print(" Open Shops are \(self.availableShopsArray)")
}
}
// still asynchronous part
enterDoStuff(true)
// call next cascade function filterClosedShops only when data
})
// Sychronous part
print("opening query start is \(openingTimeQueryStart) and opening query end is \(openingTimeQueryEnd)")
} // end of filterOpenShops()
EDIT:
I rewrote the function as:
func filterOpenShops(enterDoStuff: @escaping (Bool) -> ()) {
// get from Firebase snapshot all shops opening times into an array of tuples
//shopOpeningTimeArray:[(storeName: String, weekdayNumber: String, opening1: Sring, closing1: String, opening2:String, closing2: String)]
ref = Database.database().reference().child("Continent").child("Europe").child("Country").child("Italy").child("Region").child("Emilia-Romagna").child("City").child("Bologna").child("Shops").child("Shops Opening Times")
let query = ref?.queryOrdered(byChild: "Opening Time").queryStarting(atValue: String(describing: openingTimeQueryStart)).queryEnding(atValue: String(describing :openingTimeQueryEnd))
query?.observe(.value, with: { (snapshot) in // original is ok
// guard let data = snapshot.value as? [String:String] else { return }
for childSnapshot in snapshot.children {
print("snapshot is: \(childSnapshot)")
print("snapshot.childrend is: \(snapshot.children)")
guard let data = snapshot.value as? [String:String] else { return }
let itemToAdd = data["Shop Name"]
self.availableShopsArray.append(itemToAdd!)
print("Open Shop is: \(String(describing: itemToAdd))")
print(" Open Shops are \(self.availableShopsArray)")
}
// still asynchronous part
enterDoStuff(true)
// call next cascade function filterClosedShops only when data
print(" Open Shops are \(self.availableShopsArray)")
})
print("opening query start is \(openingTimeQueryStart) and opening query end is \(openingTimeQueryEnd)")
} // end of filterOpenShops()
but I still get a null object and not a [String:String] as expected.
The function that created the entries in Firebase is:
func postOpeningTime() {
// if shopNameTextfield.text != nil && openingTimeTextfield.text != nil && closingTimeTextfield.text != nil {
let shopName = shopNameTextfield.text!
let openingTime = openingTimeTextfield.text!
let closingTime = closingTimeTextfield.text!
// } else {return}
let post: [String:String] = [
"Shop Name" : shopName ,
"Opening Time" : openingTime ,
"Closing Time" : closingTime
]
var ref: DatabaseReference!
ref = Database.database().reference()
ref?.child("Continent").child("Europe").child("Country").child("Italy").child("Region").child("Emilia-Romagna").child("City").child("Bologna").child("Shops").child("Shops Opening Times").childByAutoId().setValue(post)
}
Now I have two behaviours:
1st: When querying for entries and finds values that are Int: completion get called but I get no snapshot print. 2nd: When querying for entries and find values that are String: completion doesn't get called but snapshot prints the right entries with values.
Can anyone please spot what's going on here?
childSnapshotfrom inside the for in loop? I'll try and printsnapshot.childreninstead before the loop - Vincenzo