Swift Firebase Get the parent value from children - swift

I have this database structure:
I am trying to get the node value (for example: -KzjZJvEQRBlRG8m2RxO) if the objectId value is equal to a specific value.
Let me give you an example:
if the object id is equal to "-Kzx6b-w3cbE_3e1MwWr" then i would like to get the node value (-Kzx6bVxJHq0HgDjkhH8) so i can delte the record.
I tried to do it like so:
let query = Api.Notification.NOTIFICATION_REF.queryOrdered(byChild: "objectId").queryEqual(toValue: id)
query.observeSingleEvent(of: .value, with: { (snapshot) in
for snap in snapshot.children {
print (snap.key)
}
However i get no value in the print statement Actually is seem not to enter at all the for cycle.
Is there a way to achieve this?
Thank you!
-----UPDATE
Would a solution like this affect the speed if i get many records?
Api.Notification.NOTIFICATION_REF.observeSingleEvent(of: .value, with: { (snapshot) in
for child in snapshot.children {
let snap = child as! DataSnapshot
let key = snap.key
Api.Notification.NOTIFICATION_REF.child(key).observeSingleEvent(of: .value, with: { (userid) in
for subChild in userid.children {
let subSnap = subChild as! DataSnapshot
let subKey = subSnap.key
//get the value here
}
})
}
})

Use snap.ref.parent?.key
Example:
query.observe(.value, with: { snap in
guard let text = snap.value as? String else { return }
print("snap parent key: \(snap.ref.parent?.key)")
}

Related

Retrieving data list from Firebase [Swift]

I'm trying to get a String array with the list of all usernames, but for some reason my code isn't working. Output should be [sean, yuh]
Database.database().reference().child("usernames").observeSingleEvent(of: .value, with: { (snapshot : DataSnapshot) in
for child in snapshot.children {
let snap = child as! DataSnapshot
let uid = snap.childSnapshot(forPath: "username")
self.array.append(uid1)
}
}
Your uid1 is not declared in the code you shared, and definitely not the value of the username property in the JSON. In addition, you'll want to get the value of the child snapshot. So combines:
Database.database().reference().child("usernames").observeSingleEvent(of: .value, with: { (snapshot : DataSnapshot) in
for child in snapshot.children {
let snap = child as! DataSnapshot
let uid = snap.childSnapshot(forPath: "username")
self.array.append(uid.value)
}
}

I want to get the child of my firebase (not the key) using swift

This is my firebase. I want to retrieve the names "anaesthesia", "musculoskeletal", "options" into an array and print it out. This is my swift code
ref?.child("mcqbase-159dc").observeSingleEvent(of: .value, with: { (snapshot) in
if snapshot.exists(){
for child in snapshot.children {
let snap = child as! DataSnapshot
let key = snap.key
self.categoriesArray.append(key)
print(self.categoriesArray)
}
}
})
It returns a blank in my terminal. Can anyone help me?
"anaesthesia", "musculoskeletal" and other your database table's names. You can change your structure to :
And your snapshot code must be :
Database.database().reference().child("names").observeSingleEvent(of: .value) { (snapshot) in
//Your code
}

How do I get specific values from children in firebase using Swift 4?

My Firebase Database
More specifically, I have randomly generated children(Listings) and from those randomly generated Listings I would like to get the string value from the keys.
For example, if I wanted the Photo URL address, I would like to get the string value of the key "PhotoURL:".
Thank you in advance !
First you need to do is to import Firebase and then call a function from the Database class like so:
let ref = Database.database().reference().child("Listings")
You can call child recursively to go deeper into your tree
//.child("Listings").child("SomeListing").child("PhotoURL")
Then call observeSingleEvent to receive the values from firebase.
Your value is stored in the snapshot variable
ref.observeSingleEvent(of: .value, with: { (snapshot) in
guard let listingsDictionary = snapshot.value as? [String: Any] else { return }
listngsDictionary.forEach({ (key, value) in
// Here you can iterate through it
})
}) { (err) in
print("Failed to fetch following listings:", err)
}
Here is the code to get child values from Listings. 
var ListArr = [ListModel]()
let ref = Database.database().reference().child("Listings")
ref.observe(.childAdded, with: { (snapshot) in
print(snapshot)
guard let dictionary = snapshot.value as? [String : AnyObject] else {
return
}
let Obj = ListModel()
Obj.UID = snapshot.key
Obj.PhotoURL = dictionary["PhotoURL"] as? String
self.ListArr.append(Obj)
}, withCancel: nil)
}
You can set up the model class
class ListModel: NSObject {
var UID:String?
var PhotoURL:String?
}

Swift Firebase - trying to retrieve more than one set of data in a function to count the number of entries

I have a problem trying to retrieve two sets of data from Firebase, in one function. The results from this retrieve will be used to update a progress bar, after the retrieve (otherwise 'zero' values) so this 'progress bar' function is also included in the Firebase function. To clarify further, I am trying to get the count of entries for 'user-posts', and 'user-plans' from the Firebase Db:-
The code for the function looks like this (and then I'll let you know what the issue is!):-
func firebaseRetrieve() {
guard let uid = Auth.auth().currentUser?.uid else {return}
let planRef = DB_BASE.child("user-plan").child(uid)
planRef.observeSingleEvent(of: .value, with: { (snapshot) in
for child in snapshot.children {
let snap = child as! DataSnapshot
let key = snap.key
self.totalPlans.append(key)
self.planCount = Double(self.totalPlans.count)
let postRef = DB_BASE.child("user-posts").child(uid)
postRef.observeSingleEvent(of: .value, with: { (snapshot) in
for child in snapshot.children {
let snaps = child as! DataSnapshot
let keys = snaps.key
self.totalPosts.append(keys)
self.postCount = Double(self.totalPosts.count)
self.fraction = self.postCount / self.planCount
//THIS IS WHERE I INPUT ANOTHER FUNCTION TO PASS THE VALUE OF 'FRACTION' INTO, THAT THNE DETERMINES THE PROGRESS BAR
}
})
}
})
THE ISSUE: The current count of 'user-plan' is 18. The current count of 'user-posts' is 14. So the fraction should equal 0.77 (78%). But, the count of 'user-posts' seems to be reiterated 18 times, so the count is 252 (i.e. 14 * 18)!! I've tried all sorts to fix it over the past 3 days, but always the same result.
Any ideas greatly received, and will stop me swearing at the wife......
you can use snapshot.childrenCount to get the count of the snapshot children , and you need to move your calculation for fraction outside the loop
checkout this code
func firebaseRetrieve()
{
guard let uid = Auth.auth().currentUser?.uid else {return}
let planRef = DB_BASE.child("user-plan").child(uid)
planRef.observeSingleEvent(of: .value, with:
{
(snapshot) in
self.planCount = snapshot.childrenCount;
for child in snapshot.children
{
let snap = child as! DataSnapshot
let key = snap.key
self.totalPlans.append(key)
}
let postRef = DB_BASE.child("user-posts").child(uid)
postRef.observeSingleEvent(of: .value, with:
{
(snapshot) in
self.postCount = snapshot.childrenCount;
for child in snapshot.children
{
let snaps = child as! DataSnapshot
let keys = snaps.key
self.totalPosts.append(keys)
}
self.fraction = self.postCount / self.planCount;
print("fraction = \(self.fraction)")
})
});
}

swift firebase nested children dictionary delete

firebase structure
In the firebase structure you can see i have to delete specific user (currentUserId) in all the groups:
it's what i try to do:
###########################UPDATED###################################
let groupsRef = self.root.child("groups")
groupsRef.observeSingleEvent(of: .value, with: { snapshot in
for groupChild in snapshot.children {
let groupSnap = groupChild as! DataSnapshot
var dict = groupSnap.value as! [String: Any]
let uid = dict["utenti"] as! [String: Bool]
for each in uid {
if each.key == self.currentUserID{
print(each.key)
//i now need a way to remove this key:value
}
}
}
})
I'm new so i'm not able to go further in extracting every key of ditcionary, than i will compare to the one i have to delete and if it's the same i will delete.
Can someone help?
let groupsRef = self.root.child("groups")
groupsRef.observeSingleEvent(of: .value, with: { snapshot in
for groupChild in snapshot.children {
let groupSnap = groupChild as! DataSnapshot
let groupKey = groupSnap.key
//added a groupKey to track the id of each group
var dict = groupSnap.value as! [String: Any]
var uid = dict["utenti"] as! [String: Bool]
//then for each key:value in uid check if is there a key = to currentuserID
for each in uid {
if each.key == self.currentUserID{
uid.removeValue(forKey: each.key)
//here you remove currentuserId from the dictionary and below
//finally you set back the new value of the dictionary without currentuserId
self.root.child("groups").child(groupKey).child("utenti").setValue(uid)
}
}
}
})
you can use
for (key, value) in uid {
}
to loop over a dictionary.
But really, looking in the official documentation of swift would give you the right answer...
let groupsRef = self.root.child("groups")
groupsRef.observeSingleEvent(of: .value, with: { snapshot in
for groupChild in snapshot.children {
let groupSnap = groupChild as! DataSnapshot
for subGroupChild in groupSnap.children {
//Here you need to remove that specific user if condition match
//specificUserUID is that user's id that user to be deleted
if let snapref = subGroupSnap as! DatabaseReference {
snapref.queryOrdered(byChild: "utenti").queryEqual(toValue: specificUserUID).observe(.childAdded, with: { (snapshot) in
snapshot.removeValue(completionBlock: { (error, reference) in
if error != nil {
print("There has been an error:\(error)")
}
})
})
}
}
}
})
Your code will go like above you just need find thaat user by user ID and delete that particular snapshot.