Fetch a specific value from Firebase - swift

I want to be able to get the address and name of the users in firebase, but I just can't find a way to do it.
Here is my best effort. This seems fine in Xcode, but the app crashes when I push the button to retrieve the values ( thread 1 exc_bad_instruction (code=exc_i386_invop subcode=0x0)
ref?.child("users").child(user)
.observeSingleEvent(of: .value, with: { (snapshot) in
let userDict = snapshot.value as! [String: Any]
let address = userDict["Address:"] as! String
let name = userDict["Name:"] as! String
print("Address: \(address) Name: \(name)")})

like #Moritz mentioned in the comment, if you force unwrap (you are telling these values won't be nil) and if one of your values turn out to be nil, it will crash the app. Try something like this -
ref?.child("users").child(user).observeSingleEvent(of: .value, with: { snapshot in
guard let userDict = snapshot.value as? [String: Any],
let address = userDict["Address:"] as? String,
let name = userDict["Name:"] as? String else {
return
}
print("Address: \(address) Name: \(name)")
})
This will not print anything if either of your Name or Address is nil

Related

Firebase: cannot retrieve children if they are less than the specified number in queryLimited

I have the following function that gets invoked when a user scrolls conversation tableview, it works well but if the remaining children are less than the specified number it retrieves none! What is more interesting is that those values appear in print(snapshot.value) but not in print(child). How can I get all nodes even if they are less than the specified number?
Thank you.
func fetchBatch(betweenUser userID: String, fromTimestamp: Double , completion: #escaping([Message]) -> ()){
guard let currentUID = Auth.auth().currentUser?.uid else { return }
var messages = [Message]()
REF_MESSAGES.child(currentUID).child(userID).queryOrdered(byChild: "timestamp").queryEnding(atValue: fromTimestamp).queryLimited(toLast: 20).observeSingleEvent(of: .value) { snapshot in
print(snapshot.value)
for child in snapshot.children {
print(child)
if let childSnapshot = child as? DataSnapshot {
guard let dictionary = childSnapshot.value as? [String: AnyObject] else {return}
let message = Message(dictionary: dictionary)
messages.append(message)
}
}
return completion(messages)
}
}
Just a guess but you may have a problem with your data structure.
That guard statement
guard let dictionary = childSnapshot.value as? [String: AnyObject] else {return}
will prevent the messages array from being fully populated when it fails.
My guess is your retrieving say, 10 child notes, then as the code iterates over them, at some point the guard statement fails due to the structure. For example a [Int: Any] instead of a [String: Any]
The end result is that not all of the child nodes are not added to the array - which in turn means there's less elements in the array than was was actually retrieved from Firebase.

Accessing firebase database returns nil swift

I want to access database through this code :
let ref = Database.database().reference()
ref.observeSingleEvent(of: .value, with: { (snapshot) in
let value = snapshot.value as? NSDictionary
print(value)
}) { (error) in
print(error.localizedDescription)
}
Here is my database :
The value printed is nil. I don't understand why...
What I tried :
I printed the value of the snapshot which is a dictionary.
I think the problem is casting the data as? NSDictionary
Can you try:
let value = snapshot.value as? [String:String]

Retrieving multiple firebase nodes swift

Im retrieving data from a firebase backend which is below. My JSON structure has 2 child notes from my understanding With the code in my view did load, i can access the users node and i can print the "email" & "provider" -
However, my main goal is to actually access the 'planits' node and get the "images" & "planit" details. I am just pretty stuck on a way to implement that. I would appreciate any and all of the help provided. Thank you!
override func viewDidLoad() {
super.viewDidLoad()
ref = Database.database().reference()
refHandle = ref.observe(DataEventType.value, with: { (snapshot) in
let dataDict = snapshot.value as! [String: AnyObject]
print(dataDict)
})
let userID = Auth.auth().currentUser?.uid
ref.child("users").child(userID!).observeSingleEvent(of: .value, with: { (snapshot) in
//Get user value
if snapshot.exists() == true {
for child in snapshot.children {
let value = snapshot.value as? NSDictionary
let EmailString = value!["email"] as! String
self.userEmail.append(EmailString)
print(self.userEmail)
// BELOW IS MY FAILED ATTEMPT AT ACCESSING THE 'planits' node - Nothing Prints
let image = value!["images"] as! String
print(image)
}
}
}) { (error) in
print(error.localizedDescription)
}

How to show data in a tableView with Firebase Realtime Database

Can anyone try to explain the steps I need to do? I get a lot of errors when I try to define my database in Xcode.
dbRef.child("class").observeSingleEvent(of: .value, with:
{ (snapshot) in
let value = snapshot().value? as? [String: AnyObject]
let description = value? ["desciption"] as? [Any]
let owner = value? ["owner"] as? [Any]
let participant = value? ["participant"] as? [Any]
let time = value? ["time"] as? [Any]
print("description: \(String(describing: description))")
print("owner: \(String(describing: owner))")
print("participant: \(String(describing: participant))")
print("time: \(String(describing: time))")
You do not need the () on snapshot().value. Make it snapshot.value as? [String: AnyObject] and that will remove the error "Cannot call value of non-function type 'DataSnapshot'"
Basically the error can be taken literally. snapshot (which is type DataSnapshot) is not a function, so you can't call it as a function i.e snapshot()

Error while parsing Json in swift 2.3

I am trying to parse this NSDictionary
{"fare":{"value":99.03,"fare_id":"12313545861568689494880005558558852","expires_at":1485864494,"display":"\u20b999.03","currency_code":"INR"},"trip":{"distance_unit":"mile","duration_estimate":720,"distance_estimate":2.76},"pickup_estimate":2}
My code is:
if let statusesArray = try? NSJSONSerialization.JSONObjectWithData(data!, options: []) as? [[String: Any]],
let user = statusesArray![0]["fare"] as? [String: Any],
let username = user["fare_id"] as? String {
// Finally we got the username
}
else
{
print("DONE")
}
But I am not getting the value fare ID. In fact its printing "DONE" from the else statement. I tried using apple's documentation of handling data,But the same error persist.
Your JSON response is Dictionary not Array, so type cast it to [String:AnyObject] and then get fare_id from the nested fare Dictionary.
if let dict = (try? NSJSONSerialization.JSONObjectWithData(data!, options: [])) as? [String: AnyObject],
let fareDict = dict["fare"] as? [String:AnyObject]
let username = fareDict["fare_id"] as? String {
print(username)
}