Swift Get Specific Value From Firebase Database - ios

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

Related

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

How to cast 'FIRDataSnapshot' to NSString & NSDict

I'm getting the error of could not cast value of type 'FIRDataSnapshot' to 'NSString'. Neither the retrieve names or retrieve quantities/manfacturers is working. Both give the same casting error essentially.
ref = Database.database().reference()
// Retrieve Names
ref.child("rawMaterials").observeSingleEvent(of: .value, with: { (snapshot) in
for child in snapshot.children {
self.rawMaterialNames.append(child as! String)
}
})
//Retrieve Quantities and Manfacturers
for name in rawMaterialNames {
ref.child("rawMaterials/\(name)").observe(.value, with: { (snapshot) in
if let data = snapshot.value as? [String: Any] {
for i in data {
let quantity = data["quantity"] as! String
let manafacturer = data["manafacturer"] as! String
self.rawMaterialManafacturers.append(manafacturer)
self.rawMaterialQuantities.append(quantity)
//self.rawMaterialQuantities.append(data!["quantity"] as! String)
//self.rawMaterialManafacturers.append(data!["manafacturer"] as! String)
}
}
})
Edit: Since, no one has been able to help, maybe I'm not providing enough. My firebase realtime database tree looks like this
App Name
-contracts
---ContractTest
-rawMaterials
---Optional("Paint")
--------manafacturer: "Optional(\"Paint Company A\")"
--------quantity: "Optional(\"120\")"
---Optional("Lead")
You are missing a step to be able to cast to String:
ref.child("rawMaterials").observeSingleEvent(of: .value, with: { (snapshot) in
for child in snapshot.children {
let nameSnapshotValue = child.value as! FIRDataSnapshot
let name = nameSnapshotValue["name"] as! String //or whatever the dictionary key is...
self.rawMaterialNames.append(name)
}
})

swift 3 firebase snapshot if value equal to ... fetch

I'm Trying to check if the rooms's value 'Owner' equals to the current user id if so then fetch all data including the key value and continue checking other children of 'rooms'
I was trying, but I fail finding the solution though it might seem easy so please help me with your suggestions or ideas. My code so far :
Database.database().reference().child("rooms").queryOrdered(byChild: "Owner").observeSingleEvent(of: .value, with: { (snapshot) in
let currentUser = Auth.auth().currentUser?.uid
if !snapshot.exists() {
print("No data found")
return
}
var rooms = snapshot.value as! [String:AnyObject]
let roomKeys = Array(rooms.keys)
for roomKey in roomKeys {
guard
let value = rooms[roomKey] as? [String:AnyObject]
else
{
continue
}
let title = value["title"] as? String
let description = value["description"] as? String
let roomPictureUrl = value["Room Picture"] as? String
let longitude = value["Longtitude"] as? String
let latitude = value["Latitude"] as? String
let dateFrom = value["Date From"] as? String
let dateTo = value["Date To"] as? String
let owner = value["Owner"] as? String
let myRooms = Room(roomID: roomKey,title: title!, description: description!, roomPicutreURL: roomPictureUrl!, longitude: longitude!, latitude: latitude!, dateFrom: dateFrom!, dateTo: dateTo!, owner: owner!)
self.rooms.append(myRooms)
self.tableView.reloadData()
print(snapshot.value)
}
})
You're missing the value in your query:
Database.database().reference()
.child("rooms")
.queryOrdered(byChild: "Owner")
.queryEqual(toValue: "STbz...")
.observeSingleEvent(of: .value, with: { (snapshot) in
See for this and more query operators, the documentation on filtering data.
Mark:- Swift 5
Database.database().reference().child("user")
.queryOrdered(byChild: "UserPhoneNumber") //in which column you want to find
.queryEqual(toValue: "Your phone number or any column value")
.observeSingleEvent(of: .value, with: { (snapshot) in
if snapshot.childrenCount > 0
{
if let snapShot = snapshot.children.allObjects as? [DataSnapshot] {
//MARK:- User Exist in database
for snap in snapShot{
//MARK:- User auto id for exist user
print(snap.key)
break
}
}
}
else if snapshot.childrenCount == 0
{
//MARK:- User not exist no data found
}
})

Firebase Accessing Snapshot Value Error in Swift 3

I recently upgraded to swift 3 and have been getting an error when trying to access certain things from a snapshot observe event value.
My code:
ref.child("users").child(userID!).observeSingleEvent(of: .value, with: { (snapshot) in
let username = snapshot.value!["fullName"] as! String
let homeAddress = snapshot.value!["homeAddress"] as! [Double]
let email = snapshot.value!["email"] as! String
}
The error is around the three variables stated above and states:
Type 'Any' has no subscript members
Any help would be much appreciated
I think that you probably need to cast your snapshot.value as a NSDictionary.
ref.child("users").child(userID!).observeSingleEvent(of: .value, with: { (snapshot) in
let value = snapshot.value as? NSDictionary
let username = value?["fullName"] as? String ?? ""
let homeAddress = value?["homeAddress"] as? [Double] ?? []
let email = value?["email"] as? String ?? ""
}
You can take a look on firebase documentation: https://firebase.google.com/docs/database/ios/read-and-write
When Firebase returns data, snapshot.value is of type Any? so as you as the developer can choose to cast it to whatever data type you desire. This means that snapshot.value can be anything from a simple Int to even function types.
Since we know that Firebase Database uses a JSON-tree; pretty much key/value pairing, then you need to cast your snapshot.value to a dictionary as shown below.
ref.child("users").child(userID!).observeSingleEvent(of: .value, with: { (snapshot) in
if let firebaseDic = snapshot.value as? [String: AnyObject] // unwrap it since its an optional
{
let username = firebaseDic["fullName"] as! String
let homeAddress = firebaseDic["homeAddress"] as! [Double]
let email = firebaseDic["email"] as! String
}
else
{
print("Error retrieving FrB data") // snapshot value is nil
}
}

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

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.

Resources