Swift 3 getting nil value in firebase while retrieving data [duplicate] - ios

This question already has answers here:
How to reload UITableView data after Firebase finishes dowload of user data?
(2 answers)
Closed 5 years ago.
I am using firebase as my backend i am trying to get the name from firebase of users and trying to display it in UITableView but i am not getting it in UITableView.
My code :-
func retriveData() {
ref.observe(.childAdded, with: { (snapshot) in
if let snapshot = snapshot.children.allObjects as? [DataSnapshot] {
for snap in snapshot {
if let userDict = snap.value as? Dictionary<String,AnyObject> {
print("user dict - \(String(describing: userDict["name"]))")
let username = userDict["name"] as? String
self.uname.append(username!)
}
}
}
})
}
My JSON:-
I have used uname array of strings and used it in UITableView delegate methods.

Reload your table view after appending the data to array:
func retriveData() {
ref.observe(.childAdded, with: { (snapshot) in
if let snapshot = snapshot.children.allObjects as? [DataSnapshot] {
for snap in snapshot {
if let userDict = snap.value as? Dictionary<String,AnyObject> {
print("user dict - \(String(describing: userDict["name"]))")
let username = userDict["name"] as? String
self.uname.append(username!)
}
}
tableView.reloadData()
}
})
}

Related

iOS Firebase asynchronous data retrieval into Array

I try to retrieve data from Firebase into Array. Because it runs asynchronously, the results that I want to show in my CollectionView is a delay until I switch back and forth. I am very new to asynchronous functions in iOS. Please help me to complete my code.
ref = Database.database().reference(withPath: "MyTest/Video")
ref?.observeSingleEvent(of: .value, with: { snapshot in
if !snapshot.exists() { return }
if let result = snapshot.children.allObjects as? [DataSnapshot] {
for child in result {
let autoID = child.key as String //get autoID
let title = snapshot.childSnapshot(forPath: "\(autoID)/Title").value
let url = snapshot.childSnapshot(forPath: "\(autoID)/URL").value
let views = snapshot.childSnapshot(forPath: "\(autoID)/Views").value
self.arrayAllTitle.append(title as! String)
self.arrayAllId.append(url as! String)
self.arrayAllDesc.append(views as! String)
}
}
})
You need to reload the collection after you retrieve the data so after the for loop call reloadData()
for child in result {
}
self.collectionView.reloadData()
//
func getValueFromDatabase(completion: #escaping (_ status: Bool) -> Void){
ref = Database.database().reference(withPath: "MyTest/Video")
ref?.observeSingleEvent(of: .value, with: { snapshot in
if !snapshot.exists() { return }
if let result = snapshot.children.allObjects as? [DataSnapshot] {
for child in result {
let autoID = child.key as String //get autoID
let title = snapshot.childSnapshot(forPath: "\(autoID)/Title").value
let url = snapshot.childSnapshot(forPath: "\(autoID)/URL").value
let views = snapshot.childSnapshot(forPath: "\(autoID)/Views").value
self.arrayAllTitle.append(title as! String)
self.arrayAllId.append(url as! String)
self.arrayAllDesc.append(views as! String)
}
completion(true)
}
else {
completion(false)
}
})
}
//
self.getValueFromDatabase { (status) in
if status {
// success
}
}
I'm working with Firebase in my project right now. I would suggest the following solution: wrap the database observer in a distinct function which gets completion block as a parameter.
func getValueFromDatabase(completion: ()->Void){
ref = Database.database().reference(withPath: "MyTest/Video")
ref?.observeSingleEvent(of: .value, with: { snapshot in
if !snapshot.exists() { return }
if let result = snapshot.children.allObjects as? [DataSnapshot] {
for child in result {
let autoID = child.key as String //get autoID
let title = snapshot.childSnapshot(forPath: "\(autoID)/Title").value
let url = snapshot.childSnapshot(forPath: "\(autoID)/URL").value
let views = snapshot.childSnapshot(forPath: "\(autoID)/Views").value
self.arrayAllTitle.append(title as! String)
self.arrayAllId.append(url as! String)
self.arrayAllDesc.append(views as! String)
}
completion()
}
})
}
This way you can call the function from anywhere providing the desired action after fetching data from db is finished:
getValueFromDatabase(completion:{
self.collectionView.reloadData() //or any other action you want to fulfil
})

Swift 3 How to get specific user id in firebase

I am using firebase as backend and I want all user id with status false.
What I am trying in my code:-
ref.child("users").child((Auth.auth().currentUser?.uid)!).child("status").queryOrdered(byChild: "status").queryEqual(toValue : "false").observe(.value) { (snapshot: DataSnapshot) in
if let snapshot = snapshot.children.allObjects as? [DataSnapshot] {
print("SNAPSHOT: \(snapshot)")
for snap in snapshot {
if let postDict = snap.value as? Dictionary<String, AnyObject> {
let key = snap.key
print(key)
print(postDict)
}
}
}
}
Find sample code below. Just verify syntax once.
ref.child("users").observe(DataEventType.value, with: { (snapshot) in
if let snapshot = snapshot.children.allObjects as? [DataSnapshot] {
print("SNAPSHOT: \(snapshot)")
for snap in snapshot {
if let userDict = snap.value as? Dictionary<String, AnyObject> {
if userDict["Status"] as? Bool == false {
let key = snap.key
print(key)
//Add this key to userID array
}
}
}
}
}

Firebase retrieve data below auto ID In Swift

I'm in trouble in retrieving data from Firebase.
I'd like to read all contactName data in JSON under auto ID , then append to UIPickerView.
Here is my JSON tree (used childByAutoId())
And Here is my Swift Code
dbRef = Database.database().reference()
dbRef.child("user").child("contacts").queryOrdered(byChild: "contactName").observeSingleEvent(of: .value, with: {(snapshot) in
for snap in snapshot.children {
let userSnap = snap as! DataSnapshot
let contactName = userSnap.value as? String
self.pickOption.append("\(contactName)")
}
})
But the result shows me all nil data... looks like this.
How Can I fix it..?
I solved myself!
But first of all, I decided not to use UIPickerView.
And what I wanna do is to add data below auto ID.
I'm not sure this is good algorithm for solving this problem, But Anyway, I made it :)
dbRef.child("user/contacts/").observe(.value, with: {(snapshot) in
if let result = snapshot.children.allObjects as? [DataSnapshot] {
for child in result {
let orderID = child.key as String //get autoID
self.dbRef.child("user/contacts/\(orderID)/contactName").observe(.value, with: { (snapshot) in
if let nameDB = snapshot.value as? String {
if self.debtorName == nameDB {
self.dbRef.child("user/contacts/\(orderID)").updateChildValues(data)
}
}
})
}
}
})

How to retrieve data from current User in Firebase using Swift?

I am trying to get current users firstname from firebase using swift code. Below is my JSON file and swift code. But it's not retrieving first name. Please suggest
Json:
Swift code:
if FIRAuth.auth()?.currentUser != nil{
let queryRef = FIRDatabase.database().reference().child("expatsappmembers")
let userID : String = (FIRAuth.auth()?.currentUser?.uid)!
print("Current user ID is" + userID)
queryRef.child("uid").child(userID).observeSingleEvent(of: .value, with: {(snapshot) in
print(snapshot.value)
let userName = (snapshot.value as! NSDictionary)["firstname"] as! String
print(userName)
})
}
It is slightly different to get a value from Firebase in Swift 3
the proper way to do it is:
ref.child("expatsappmembers").queryOrderedByKey().observeSingleEvent(of: .value, with: { (snapshot) in
// Get user value
let value = snapshot.value as? NSDictionary
let firstName = value?["firstname"] as? String
// ...
}) { (error) in
print(error.localizedDescription)
}

Retrieving and Reading Data as NSArray from Firebase (Swift 3)

I'm working through a course on Udemy to build a chat app with Firebase, Backendless, and Swift. All of the issues (it was written for Swift 2 not 3) I've been able to resolve myself, but this one has me stumped. This function is supposed to retrieve data from the Firebase database, and apparently it was supposed to retrieve it as an NSArray, but it now retrieves it as an NSDictionary, which is making a huge list of errors in the other functions because it's not expecting a dictionary.
func loadRecents() {
firebase.childByAppendingPath("Recent").queryOrderedByChild("userId").queryEqualToValue(currentUser.objectId).observeEventType(.Value, withBlock: {
snapshot in
self.recents.removeAll()
if snapshot.exists() {
let sorted = (snapshot.value.allValues as NSArray).sortedArrayUsingDescriptors([NSSortDescriptior(key: "date", ascending: false)])
}
})
}
I've updated to Swift 3 as far as:
func loadRecents() {
ref = FIRDatabase.database().reference()
let userId = currentUser?.getProperty("username") as! String
ref.child("Recent").queryOrdered(byChild: "userId").queryEqual(toValue: userId).observe(.value, with: {
snapshot in
self.recents.removeAll()
if snapshot.exists() {
let values = snapshot.value as! NSDictionary
}
})
}
Of course, using as! NSArray does not work. Would very much appreciate it if anyone can suggest a method to update this to use Swift 3, sort it by a value in the data, and be able to access it later on. Thanks!
func loadRecents() {
ref = FIRDatabase.database().reference()
let userId = currentUser?.getProperty("username") as! String
ref.child("Recent").queryOrdered(byChild: "userId").queryEqual(toValue: userId).observe(.value, with: {
snapshot in
self.recents.removeAll()
if snapshot.exists() {
let values = snapshot.value as! [String:AnyObject]
}
})}
or you can use also let values = snapshot.value as! [Any]
Hope this will help you, try this code:
func loadRecents() {
let ref = FIRDatabase.database().reference()
let userId = currentUser?.getProperty("username") as! String
ref.child("Recent").queryOrdered(byChild: "userId").queryEqual(toValue: userId).observe(.value, with: {
snapshot in
self.recents.removeAll()
guard let mySnapshot = snapshot.children.allObjects as? [FIRDataSnapshot] else { return }
for snap in mySnapshot {
if let userDictionary = snap.value as? [String: Any] {
print("This is userKey \(snap.key)")
print("This is userDictionary \(userDictionary)")
}
}
})
}

Resources