How to retrieve nested nodes from Firebase realtime database to iOS app - ios

I'm building a simple app which stores and retrieve data from firebase realtime database. At present my database has these data of an user.
Database content
Here is the code which I used to insert data.
let ref = Database.database().reference()
let user = ref.child("bill")
user.setValue(["name":"Bill gates"])
user.child("Request/One").setValue(["Phno":" ","Message":" "])
As you can see I'm inserting a dictionary with empty values because I don't know how to create a child node without any data within them.
I'm trying to retrieve the Request part of the database completely whenever a new node is added as a child to request node.
Here I my code for retrieving
user.observe(.childAdded) { (DataSnapshot) in
for case let i as DataSnapshot in DataSnapshot.children
{
guard let dict = i.value as? [String:Any] else{print("Error"); return}
let a = dict["Message"] as? String
let b = dict["Phno"] as? String
print(a!)
print(b!)
}
}
But in above code it doesn't get called when I explicitly add a new node in database

Solved it by using below code
user.observe(.childAdded) { (DataSnapshot) in
if let dict = DataSnapshot.value as? NSDictionary
{
for i in dict.allKeys
{
if let data = dict[i] as? NSDictionary
{
let message = data["Message"] as! String
let phno = data["Phno"] as! String
if(message != "" && phno != "")
{
print(message)
print(phno)
}
}
}
}

Related

Retrieve last child from child node firebase realtime database swift 4

This is my firebase realtime database
Image link
This is the snippet i am using its always returning nil
let rootRef = Database.database().reference()
rootRef.child("POSTS").queryLimited(toLast: 1).observeSingleEvent(of: .value) { (myDataSnap) in
let value = myDataSnap.value as? NSDictionary
print(value as? Any)
}
If you are trying to access Id and Id's can be anything other than 0.
Than you can try the snippet below
let Key = rootRef.child("POSTS").childByAutoId().key
rootRef.child("POSTS").child(Key!).setValue(postData.toDictionary()){
(error:Error?, ref:DatabaseReference) in
if let error = error {
print("Data could not be saved: \(error).")
} else {
//do stuff
}
}
Use .childAdded or childChanged instead of .value, this might solve it
let rootRef = Database.database().reference()
rootRef.child("POSTS").queryLimited(toLast: 1).observeSingleEvent(of: .childChanged) { (myDataSnap) in
let value = myDataSnap.value as? NSDictionary
print(value as? Any)
}

Retrieving object from a node in Firebase if the node has currentuser.uid object and display in my UITableViewCell

My db structure is in my iOS app
I need to retrieve all fridges that the current user's id and display in a table view. After browsing through all threads for a good amount of time I haven't got the right answer.
Here is my Swift code that doesn't do what I need. I believe I am messing up with queries:
let fridgeDB = Database.database().reference()
let fridgeDBRef = fridgeDB.child("fridges")
guard let uid = Auth.auth().currentUser?.uid else {return}
let queryRef = fridgeDBRef.queryOrdered(byChild: uid)
queryRef.observe(.childAdded) { snapshot in
let snapshotValue = snapshot.value as! Dictionary<String,AnyObject>
print("snapshotValue: \(snapshotValue)")
let name = snapshotValue["FridgeName"]!
let fridge = Fridge()
fridge.fridgeName = name as! String
self.fridgeUnits.append(fridge)
self.configureTableView()
self.fridgeList.reloadData()
You are pretty close.
Your query needs to do two things 1) define the node to query on, and 2) define what your want to query for.
The node you want to query on is actually the uid, and you want to query to see if it's true.
let itemsRef = self.ref.child("fridges")
let thisUserQuery = itemsRef.queryOrdered(byChild: uid).queryEqual(toValue: true)
thisUserQuery.observeSingleEvent(of: .value, with: { snapshot in
guard let foundFridges = snapshot.children.allObjects as? [DataSnapshot] else {return}
for fridge in foundFridges {
let name = fridge.childSnapshot(forPath: "FridgeName").value as! String
print(fridge.key, name)
}
})

How to get values inside nested keys in Firebase on Swift

I'm trying to get values inside two nested keys in Firebase.
:
I need to put all the value of name inside an array. Here is my code where I'm accessing just the node "user". I was thinking that I could use "queryOrderedByKey" one after another, but in that case xCode crashes and says something like multiple quires aren't allowed.
Database.database().reference().child("user").queryOrderedByKey().observe(.childAdded) { (snapshot) in
if snapshot.value != nil {
let result = snapshot.value as! [String : AnyObject]
if let name = result["name"] as? String {
self.myArray.append(name)
}
DispatchQueue.main.async(execute: {
self.tableView.reloadData()
})
}
}
And this is what I'm getting when printing the result.
Here is the answer
Database.database().reference().child("user").observe(.childAdded) { (snapshot) in
if let dictinoary = snapshot.value as? [String: Any] {
if let myFinalStep = dictinoary["GeneralInformation"] as? [String: Any] {
print(myFinalStep["name"])
}
}
}
Tigran's answer is very good but here's an alternative. This code iterates over each child node within 'user' node and looks into a deep path to get the name. Note this leaves a childAdded observer to the user node so if any additional nodes are added, this will fire again.
let usersRef = self.ref.child("user")
usersRef.observe(.childAdded, with: { snapshot in
if let name = snapshot.childSnapshot(forPath: "GeneralInformation")
.childSnapshot(forPath: "name").value as? String {
print(name)
}
})
If you want to read the names in once and not leave an observer, here's an alternative
let usersRef = self.ref.child("user")
usersRef.observeSingleEvent(of: .value, with: { snapshot in
for child in snapshot.children {
let snap = child as! DataSnapshot
if let name = snap.childSnapshot(forPath: "GeneralInformation")
.childSnapshot(forPath: "name").value as? String {
print(name)
}
}
})
I was feeling Swifty so here's a third variant if you don't want to leave an observer. Note that if the node containing the name does not exist, the resulting array will contain "No Name" at that index.
let usersRef = self.ref.child("uses")
usersRef.observeSingleEvent(of: .value, with: { snapshot in
let myUsers = snapshot.children.allObjects.map { $0 as! DataSnapshot }
let names = myUsers.map { $0.childSnapshot(forPath: "GeneralInformation")
.childSnapshot(forPath: "name")
.value as? String ?? "No Name" }
print(names)
})

I am trying to fetch data from Firestore database in my ios Swift Project

I want to fetch data from team of subscription collection.
I am trying following code:
db.collection("subscriptions").addSnapshotListener { querySnapshot, error in
guard let snapshot = querySnapshot else {
print("Error retreiving snapshots \(error!)")
return
}
//print("Current data: \(snapshot.documents.map { $0.data() })")
for document in snapshot.documents{
print(document.data())
}
}
Output of my Code
So, as far concern i am able to fetch the data of collections but not able to get data from team , help me out , Thanx for support
If you don't want to listen every event use getDocuments method instead of addSnapshotListener.
/// This will give you team data
document.data()["team"]
After getting the team information from firestore. Here is how to get name and officeId:
if let teamInfo = document.data()["team"] as? [String: Any] {
let teams = teamInfo.map {$0.value}
for team in teams {
guard let validTeam = team as? Dictionary<String, Any> else {continue}
let name = validTeam["name"] as? String ?? ""
let officeId = validTeam["officeId"] as? String ?? ""
print("name: \(name), officeId: \(officeId)")
}
}
Output
name: Developer Ratufa, officeId: myuPlTBO8sEM4SOQ8rWY
name: , officeId: myuPlTBO8sEM4SOQ8rWY

Read array inside snapshot in Firebase with Swift

Need help trying to read an array of this form:
As far as I tried, I got this
let defaults = UserDefaults.standard
let userUuid = defaults.string(forKey: defaultsKeys.keyOne)
let ref = FIRDatabase.database().reference().child("images").child("\(userUuid!)")
let filterQuery = ref.queryOrdered(byChild: "uuid").queryEqual(toValue: "\(uuid)") // where uuid is a value from another view
filterQuery.observe(.value, with: { (snapshot) in
for images in snapshot.children {
print(images)
}
})
But I receive nothing. I want to read the images' links to show them in the view controller.
Make sure that the uuid var in the line below is not an optional value (or if it is, unwrap it) because otherwise you'll be querying to compare to "Optional(myUuidValue)" instead of "myUuidValue"
let filterQuery = ref.queryOrdered(byChild: "uuid").queryEqual(toValue: "\(uuid)")
The snapshot in the line below contains more than just the images, it has all the other children under that uuid
filterQuery.observe(.value, with: { (snapshot) in })
So extract the images like this:
filterQuery.observe(.value, with: { (snapshot) in
let retrievedDict = snapshot.value as! NSDictionary
let innerDict = retrievedDict["KeyHere"] as! NSDictionary // the key is the second inner child from images (3172FDE4-...)
let imagesOuterArray = userDict["images"] as! NSArray
for i in 0 ..< imagesOuterArray.count {
let innerArray = imagesOuterArray[i] as! NSArray
for image in innerArray {
print(image as! String)
}
}
})
Clarification: cast all the children of the uuid as an NSDictionary, then extract the nested arrays using those two for-loops
Update
Thanks to Jay for pointing out the error! Also, as Jay suggested, consider restructuring your database and replacing those arrays with dictionaries that perhaps contain the URL, path (for deleting purposes if you need that), and timestamp of each image.
After strugling for the answer, got this code works
let ref = FIRDatabase.database().reference().child("images").child("\(userUuid!)")
let filterQuery = ref.queryOrdered(byChild: "identifier").queryEqual(toValue: "\(identifier)")
filterQuery.observe(.value, with: { (snapshot) in
for child in snapshot.children {
if (child as AnyObject).hasChild("images") {
let images = (images as AnyObject).childSnapshot(forPath: "images").value! as! NSArray
for i in images {
for j in i as! [AnyObject] {
let url = NSURL(string: j as! String)
//Then downloaded the images to show on view
URLSession.shared.dataTask(with: url! as URL, completionHandler: { (data, response, error) in
if error != nil {
print(error)
return
}
//Code to show images..
}).resume()
}
}
}
}
})
Can i receive feedback about this?

Resources