How To Search in Database Firebase - swift

I did my search on Stackoverflow but I didn't find the solution I'm looking for
I want to search in database firebase if The "Name" is equal to The name in Navigation Title and also the "Email" that user use to signIn is equal to The Email in Database then it will avoid user to add new item
The Json looks like this
"Items" : {
"-KUMSKLFqMjclbqygnPL" : {
"Item" : "asdfg"
"Name" : "Fadi”,
"User Email" : "i#i.com"
}
}
My code is
let databaseRef = FIRDatabase.database().reference()
var NAME : String!
var UserEmail : String!
var email : String!
databaseRef.child("Items").queryOrderedByKey().observe(.childAdded, with: { snapshot in
let snapshotValue = snapshot.value as? NSDictionary
NAME = (snapshotValue?["Name"] as? String)!
UserEmail = (snapshotValue?["User Email"] as? String)!
email = (FIRAuth.auth()?.currentUser?.email)!
if NAME == navigationItem.title {
if UserEmail == email {
print ("you can't add new item \(UserEmail)")
}else if UserEmail != email {
print("you can add new Item")
}
}
})
My problem is If there is name equal Fadi but there are two different emails
The result will be
you can't add new item Optional("i#i.com")
you can add new Item
It should print only
you can't add new item Optional("i#i.com")
I don't know how to Break it , Right now it's looks like it looping through all database
Updated :
I try the Dravidian answer
Result of print(snapShot.value) :
"-KUMS7J-rCglHrVGX840" = {
"Item" = "asdsd"
"Name" = "a";
"User Email" = "a#a.com";
};
The result is right! but now I need to extract User Email from that node

If you are looking for finding the node which has a specific name try this:-
let databaseRef = FIRDatabase.database().reference()
databaseRef.child("Items").queryOrdered(byChild: "Name").queryEqual(toValue: "Fadi").observeSingleEvent(of: .value, with: { (snapShot) in
if let snapDict = snapShot.value as? [String:AnyObject]{
for each in snapDict{
let key = each.key as! String
let name = each.value["Name"] as! String
print(key)
print(name)
}
}
}, withCancel: {(Err) in
print(Err.localizedDescription)
})

Related

retrieving data from auto id database child

I'm kinda new on swift programming, my case is:
I have a database on firebase realtime "see picture", I want to retrieve the firstName and lastName data of a specific ID only.
for example:
When i'm at login screen and logged in using this email: "ali_y_k#hotmail.com", and when going to the next screen i want to display the firstName and lastName of this email in the text fields showing on picture
I have tried several solutions but the problem always was I can't enter the random IDs child to fetch the firstName and lastName
there is what i tried:
First
func retriveInfo () {
let databaseRef = Database.database().reference().child("User_Informations")
databaseRef.observe(.childAdded) { (snapshot) in
let snapshotValue = snapshot.value as! Dictionary<String,String>
let firstName = snapshotValue["firstName"]!
let lastName = snapshotValue["lastName"]!
let email = snapshotValue["email"]!
print(firstName,lastName,email)
}
}
This is printing all data (firstName,lastName,email) from every id
Second
func retriveInfo() {
let databaseRef = Database.database().reference().child("User_Informations")
databaseRef.observeSingleEvent(of: .value, with: { (snapshot) in
for snap in snapshot.children {
let userSnap = snap as! DataSnapshot
let uid = userSnap.key //the uid of each user
let userDict = userSnap.value as! [String:AnyObject] //child data
let firstName = userDict["firstName"] as! String
let lastName = userDict["lastName"] as! String
print("key = \(uid) First Name = \(firstName), Last Name = \(lastName)")
}
})
This will print every key "Id" and all the info
Thank You in advance :)
Since you have childByAutoId you have to use query ordered and query equal.
let reference = Database.database().reference().child("User_Informations").queryOrdered(byChild: "email")
reference.queryEqual(toValue: "ali_y_k#hotmail.com").observeSingleEvent(of: .childAdded) { (snapshot) in
let dictionary = snapshot.value as! [String : Any]
let firstName = dictionary["firstName"]
print(firstName)
}
You need to use the current user id after you login
let currentUserUid = FIRAuth.auth()!.currentUser!.uid
let databaseRef = Database.database().reference().child("User_Informations/\(currentUserUid)")
databaseRef.observeSingleEvent(of: .value, with: { (snapshot) in
}

How to retrieve data from all the Users using Firebase and Swift

i have a firebase databank looking like this(Json):
{
"user" : {
"UVHpZfD60EWcYDbeV60ENqXaioA3" : {
"email" : "thisisanothertest#gg.gg",
"location" : {
"latitude" : 37.785834,
"longitude" : -122.406417
},
"profile" : {
"alter" : "23",
"geschlecht" : "männlich",
"name" : "Mario1"
}
},
"nEsKd9uIOnSmVuMbAK0K2X1Dz6A3" : {
"email" : "thisisatest#gg.gg",
"location" : {
"latitude" : 37.785834,
"longitude" : -122.406417
},
"profile" : {
"alter" : "23",
"geschlecht" : "männlich ",
"name" : "Mario"
}
}
}
Problem:
Now i would like to get the Locations from all the users (latitude and longitude) to place them later on on a Map.
I can get the location for a single user realy easy by doing the below code. But how can i get the data from all the users at once?
var ref: DatabaseReference!
ref = Database.database().reference()
let userID = Auth.auth().currentUser?.uid
ref.child("user").child(userID!).child("location").observeSingleEvent(of: .value, with: { (snapshot) in
// Get user value
let value = snapshot.value as? NSDictionary
let lat = value?["latitude"] as? Double ?? 0.0
let long = value?["longitude"] as? Double ?? 0.0
I found a similar question already here
So i tried that code from the above link:
let usersRef = ref.child("users")
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 location = userDict["Location"] as! String
print("key = \(uid) is at location = \(location)")
}
})
But with that pice of code i was only able to get all the email adresses. By changing the "Location" to "email". How can i go down one more node to access the "location" node and get the latitude and longitude of all the users?
Thank you :)
Looks like you misspelled the location key for your dictionary:
let location = userDict["Location"] as! [String: AnyObject]
Replace it with:
let location = userDict["location"] as! [String: AnyObject]
You can always put a breakpoint at the print line and see what your location dictionary looks like with po location in console.
As you can see in your data location is stored as another object, so you have to cast it as Dictionary => [String:AnyObject]
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 location = userDict["location"] as! [String:AnyObject]
print("key = \(uid) is at location = \(location)")
}

Having trouble trying to obtain value from Firebase

I'm trying to get a value inside a Firebase database I set up but I'm having issues trying get it out. There is a section in my program where I go through each child under Cities and obtain the the name of each city. I thought it would be a good idea to try to obtain the status for each city in the same section but I can't get it out. Below is a sample of the JSON object. I feel like I'm close but missing something to put it all together.
"Users" : {
"NPNBig20BXNpX4Rz0UbMyiKAarY2" : {
"Cities" : {
"New York City" : {
"Status" : "Empty"
},
"Atlanta" : {
"Status" : "Empty"
},
"Test City" : {
"Status" : "Wow",
"Value" : "Test"
}
},
"Email" : "fakeemail#gmail.com"
}
}
Code:
guard let uid = userID else { return }
let databaseRef = Database.database().reference(fromURL: "https://testApp.firebaseio.com/").child("Users").child(uid).child("Cities")
var dataTest : [String] = []
//var cityDictionary: [String:String]()
databaseRef.observeSingleEvent(of: .value, with: {(snapshot) in
for child in snapshot.children {
let snap = child as! DataSnapshot
let key = snap.key
guard let value = snap.value else { return }
//let testData = value["Status"] **Type Any has no subscript
print("Key: ", key, "\nValue: ", value)
dataTest.append(key)
}
completion(dataTest)
})
This is the printed output
Key: New York City
Value: {
Status = Empty;
}
Key: Sintra
Value: {
Status = Empty;
}
Key: Test City
Value: {
Status = Wow;
Value = Test;
}
Here is the way you can get Status from your value:
if let value = snap.value as? [String: AnyObject] {
let Status = value["Status"] as? String ?? ""
}
And your complete code will be:
guard let uid = userID else { return }
let databaseRef = Database.database().reference(fromURL: "https://testApp.firebaseio.com/").child("Users").child(uid).child("Cities")
var dataTest : [String] = []
//var cityDictionary: [String:String]()
databaseRef.observeSingleEvent(of: .value, with: {(snapshot) in
for child in snapshot.children {
let snap = child as! DataSnapshot
let key = snap.key
guard let value = snap.value else { return }
//let testData = value["Status"] **Type Any has no subscript
if let value = snap.value as? [String: AnyObject] {
let Status = value["Status"] as? String ?? ""
}
print("Key: ", key, "\nValue: ", value)
dataTest.append(key)
}
completion(dataTest)
})
func handleGetCities(_ completion: #escaping ([String]) -> ()) {
guard let uid = Auth.auth().currentUser?.uid else { return }
// OR
guard let uid = userID else { return }
// THEN
var data: [String] = []
let reference = Database.database().reference()
reference.child("Users").child(uid).child("Cities").observe(.childAdded, with: { (snapshot) in
let city_name = snapshot.key
data.append(city_name)
completion(data)
}, withCancel: nil)
}

Retrieve / read data from Firebase database

I am using this code to retrieve data from a Firebase database. However, I am only able to pull one variable at a time. Can you please help me find a way to pull the others (student names, title etc.) and save them to an object arrayList?
{
"projects" : [
1, {
"answer1" : false,
"answer2" : true,
"answer3" : true,
"campus" : "Science Academy",
"category" : "LifeScience",
"question1" : "This is question 1",
"question2" : "This is question 2",
"question3" : "This is question 3",
"student1" : "john",
"student2" : "Kyle",
"title" : "Amazon Forest"
}
]
}
var ref : DatabaseReference?
var handle : DatabaseHandle?
ref = Database.database().reference()
handle = ref?.child("projects").child("1").child(question1).observe(.value, with: { (snapshot) in
if let question = snapshot.value as? String {
print(question)
}
})
IF your database has more that just projects/1 and you're wanting to access projects/1-2-3-4 etc. then you'll want to do something like this:
let reference = Database.database().reference()
reference.child("projects").observe(.childAdded, with: { (snapshot) in
let key = snapshot.key // THIS WILL GET THE PROJECT THAT IT'S IN. 1, 2, 3, 4 etc.
guard let dictionary = snapshot.value as? [String: AnyObject] else { return }
let answer1 = dictionary["answer1"] as? Bool
let campus = dictionary["campus"] as? String
}, withCancel: nil)
IF you're wanting to simple get a hold of all the values inside of project/1 and not just the questions, you'll want to do something like this:
let reference = Database.database().reference()
reference.child("projects").child("1").observeSingleEvent(of: .value, with: { (snapshot) in
let key = snapshot.key // THIS WILL GET THE PROJECT THAT IT'S IN. 1, 2, 3, 4 etc.
guard let dictionary = snapshot.value as? [String: AnyObject] else { return }
let answer1 = dictionary["answer1"] as? Bool
let campus = dictionary["campus"] as? String
}, withCancel: nil)

Download address from firebase in mapView

Trying to upload an address from firebase and post it on mapView. But for some reason the address doesn't want to unload. The address spelled out by the string in firebase example - Moscow, Street so-and-so, house 1. What could be the reason for not loading the data?
var allAddresses: String = ""
addressRef = Database.database().reference(withPath: "Address")
addressRef.observe(.value, with: { (snapshot) in
let value = snapshot.value as! NSDictionary
self.allAddresses = value["address"] as? String ?? ""
})
}
Firebase:
{
«Address» : {
«AddressOne» : {
"address" : "Москва, Пресненская набережная д.8, квартира 195, подъезд 94",
},
"AddressTwo» : {
"address" : "Москва, ул. Правды д.24 строение 3",
},
"AddressThree» : {
"address" : "Москва,ул.Электрозаводская д.21",
}
}
}
You're attaching a value observer to /Address, which means that you get a snapshot with all data at that location. Since there are multiple child addresses, your code will need to handle those.
The simplest way to do that is by listening for .childAdded instead of .value:
var allAddresses: String = ""
addressRef = Database.database().reference(withPath: "Address")
addressRef.observe(.childAdded, with: { (snapshot) in
let value = snapshot.value as! NSDictionary
self.allAddresses = value["address"] as? String ?? ""
})
Now your code gets triggered with each individual address.
You can also stick to observing .value and then loop over the results in the snapshot:
var allAddresses: String = ""
addressRef = Database.database().reference(withPath: "Address")
addressRef.observe(.value, with: { (snapshot) in
for address in snapshot.children.allObjects as [FIRDataSnapshot] {
let value = address.value as! NSDictionary
self.allAddresses = value["address"] as? String ?? ""
})
})
Use optional unwrapping and set breakpoints on some lines to see where your code doesn't do what you want :
var allAddresses: String = ""
addressRef.observe(.value, with: { (snapshot) in
if let value = snapshot.value as? [String:Any] {
if let address = value["address"] as? String {
self.allAddresses = address
} else {
print("no address in value")
}
} else {
print("no value from firebase")
}
})
}
You should also use swift types in swift, it's a good practice.