Firebase process child snap that has dictionary inside it in Swift 3 - ios

I'm trying to get back information from some users in Firebase.To do that, I'm running a query that selects the users based on the user's id I passed.The problem is that, inside the user object, there is another object and when I try to get the entire user in my code, I only get that last object.
This is what a user looks like in Firebase:
USERIDHERE
{
"coins" : 4850,
"name" : "Jogador 1020",
"score" : 22,
"unlocked" : {
"000" : true,
"KA0293" : true
}
}
This is the code to get the user
ref.child("users").child(key).observeSingleEvent(of: .value, with: { (snapshot) in
for snap in snapshot.children.allObjects as! [FIRDataSnapshot] {
if let dict = snap.value as? Dictionary<String,AnyObject> {
print(dict)
}
}
})
When I print the dict, instead of getting all the user information, I only get in this example the following output:
["000": 1, "KA0293": 1]

Database:
Code:
let ref = FIRDatabase.database().reference()
let refUsers = ref.child("users")
let refUser = refUsers.child("123")
refUser.observeSingleEvent(of: .value) { (snap: FIRDataSnapshot) in
if snap.exists() {
if let dict = snap.value as? [String: Any] {
print(dict)
}
}
}
Print's output:
["unlocked": {
000 = 1;
KA0293 = 1;
}, "name": Jogador 1020, "score": 22, "coins": 4850]

ref.child("users").child(key).observeSingleEvent(of: .value, with: { (snapshot) in
// you can get your user's name like below:
username = (snapshot.value as? NSDictionary)?["name"] as! String
if let dict = snapshot.value as? Dictionary<String,AnyObject> {
print(dict)
}
})
Snapshot already has user's all information.

Related

Firebase -How to loop through snapshot.hasChild("...")

My database is laid out like below
users
|
#--uidABC
|
|---phone:"+13125550690"
|
|---followers
|
|----uid123
| |---timeStamp:111222
|
|----uid456
| |---timeStamp:777999
I use .observeSingleEvent to check to see if uidABC exists and if it does I want to check to see if there is a child named followers under that path.
I can use snapshot.hasChild("followers") to see if it's available and if it is how can I loop through all the children underneath snapshot.hasChild("...")?
I use the code below but it's looping through the wrong snapshot. It using the top level one when it should use whatever DataSnapshot is under followers
let ref = Database...child("users").child(uidABC)
ref.observeSingleEvent(of: .value, with: { (snapshot) in
if !snapshot.exists() {
// this user doesn't exist
return
}
if !snapshot.hasChild("followers") {
// this user exists but has no followers
return
}
// this user exists and has followers now loop through them
for uid in snapshot.children {
let snapshot = uid as! DataSnapshot
if let dict = snapshot.value as? [String:Any] {
let timeStamp = dict["timeStamp"] as? Double
// eg. check for a specific timeStamp
}
}
})
I got the answer from here and here
let ref = Database...child("users").child(uidABC)
ref.observeSingleEvent(of: .value, with: { (snapshot) in
if !snapshot.exists() {
// this user doesn't exist
return
}
if !snapshot.hasChild("followers") {
// this user exists but has no followers
return
}
// this user exists and has followers now loop through them
let childSnapshot = snapshot.childSnapshot(forPath: "followers") {
for child in childSnapshot.children {
let snap = child as! DataSnapshot
let uid = snap.key
if let dict = snap.value as? [String: Any] {
let timeStamp = dict["timeStamp"] as? Double ?? 0
// eg. check for a specific timeStamp
}
}
})
Use child:
// this user exists and has followers now loop through them
for uid in snapshot.childSnapshot("followers") {
guard let snapshot = uid as! DataSnapshot else {
// Followers error
}
if let dict = snapshot.value as? [String:Any] {
let timeStamp = dict["timeStamp"] as? Double
// eg. check for a specific timeStamp
}
}
You can find more here:
Iterate over snapshot children in Firebase

Firebase retuns incored snapshot swift

I have a firebase chat application and I am trying to get user credentials but I am getting wrong values from the firebase in my console
that is what my ref and snapshot is and when I decide to print this in the console I get this
CREDENTiL data ref Optional({
"cc71128f-99a7-4435-879b-b1d0c7ce9c37" = {
location = "-Lav1QzhaoRMGAJHy8nQ";
};
})
CREDENTiL data ref Optional({
email = "adie.olalekan#max.ng";
name = "Olalekan Adie";
profilePicLink = "http://www.freeiconspng.com/uploads/profile-icon-9.png";
})
this is my code
self.allUserRef?.observe(.childAdded, with: { (snapshot) in
let id = snapshot.key
print("CREDENTiL data ref \(snapshot.value)")
if let data = snapshot.value as? [String: AnyObject] {
if snapshot.hasChild("credentials") {
print("CREDENTiL data \(data)")
if let credentials = data["credentials"]! as? [String: AnyObject] {
print("CREDENTiL \(credentials)")
if id != exceptID {
let userInfo = ChatUser(dictionary: data as NSDictionary)
}
}
}
}
})
Any help would be appreciated
let refer = Database.database().reference()
refer.child("chatUsers").child("your uid").observe(.childAdded, with: { (snapshot) in
let id = snapshot.value//your snapshot
if((((snapshot.value as! NSDictionary).allKeys) as! NSArray).contains("credentials"))
{
print("credentials",snapshot.value)
}
})
Please try above code to get your credentials as snapshot.

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)
})

Firebase Multi Level Database into tableview

How do I get data from a child deeper into a database that has an unknown name?
My example structure is below.
This code works (to get the snapshot data) but I am hardcoding the second child. I will not always know this value (Bus 1).
let ref = FIRDatabase.database().reference()
let usersRef = ref.child("Trips").child("Bus 1")
usersRef.observeSingleEvent(of: .value, with: { (snapshot) in
for snap in snapshot.children {
let userSnap = snap as! FIRDataSnapshot
let uid = userSnap.key //the uid of each user
let userDict = userSnap.value as! [String:AnyObject] //child data
let personOn = userDict["getOn"] as! String
print("key = \(uid) is at getOn = \(personOn)")
}
})
This will print:
key = Stop 1 is at getOn = 3
key = Stop 2 is at getOn = 7
Should I be structuring this differently? Flatter?
Thanks and let me know of any questions.
This is a more preferable way as I have a class for TripDetails which goes into an array to load into the table. But again, I do not know what the second child's name is.
FIRDatabase.database().reference().child("Trips").child("Bus 1").observe(.childAdded, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject] {
let trip = TripDetails()
trip.setValuesForKeys(dictionary)
self.trips.append(trip)
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
print(snapshot)
}, withCancel: nil)
I'm still not super sure what data you want exactly. If all you want is all the data you can just do this.
let ref = FIRDatabase.database().reference().child("Trips")
ref.observeSingleEvent(of: .value, with: { snapshot in
let enumerator = snapshot.children
while let bus = enumerator.nextObject() as? FIRDataSnapshot {
print("\(bus.key)")
let enumerator = bus.children
while let stop = enumerator.nextObject() as? FIRDataSnapshot {
let stopDict = stop.value as? [String: Any]
let uid = stop.key
let personOn = stopDict?["getOn"] as? String
print("key = \(uid) is at getOn = \(personOn)")
}
}
})

Swift Get Specific Value From Firebase Database

I'm trying to get a specific value from Firebase Database. I looked some of the documents such as Google's, but I couldn't do it. Here is the JSON file of the database:
{
"Kullanıcı" : {
"ahmetozrahat25" : {
"E-Mail" : "ahmetozrahat25#gmail.com",
"Yetki" : "user"
},
"banuozrht" : {
"E-Mail" : "banuozrahat#gmail.com",
"Yetki" : "user"
}
}
}
Swift Code:
ref?.child("Kullanıcı").child(userName.text!).observeSingleEvent(of: .value, with: { (snapshot) in
if let item = snapshot.value as? String{
self.changedName = item
}
})
I want to get E-Mail value of a user, not everybody's. How can I do that?
At last I found a solution. If I declare a var and try to use later it returns nil, but if I try use snapshot.value as? String it's ok. Here is a example I did.
ref: FIRDatabaseReference?
handle: FIRDatabaseHandle?
let user = FIRAuth.auth()?.currentUser
ref = FIRDatabase.database().reference()
handle = ref?.child("Kullanıcı").child((user?.uid)!).child("Yetki").observe(.value, with: { (snapshot) in
if let value = snapshot.value as? String{
if snapshot.value as? String == "admin"{
self.items.append("Soru Gönder")
self.self.tblView.reloadData()
}
}
})
In your code, the snapshot will contain a dictionary of child values. To access them, cast the snapshot.value as a Dictionary and then accessing the individual children is a snap (shot, lol)
ref?.child("Kullanıcı").child(userName.text!)
.observeSingleEvent(of: .value, with: { (snapshot) in
let userDict = snapshot.value as! [String: Any]
let email = userDict["E-Mail"] as! String
let yetki = userDict["Yetki"] as! String
print("email: \(email) yetki: \(yetki)")
})
Add the "E-Mail" child to the query.
ref?.child("Kullanıcı").child(userName.text!).child("E-Mail").observeSingleEvent(of: .value, with: { (snapshot) in
if let item = snapshot.value as? String{
self.changedName = item
}
})

Resources