I am trying to fetch all the driveways which belongs to user using their email as the search key.
And here is the code I am writing:
guard let currentUser = FIRAuth.auth()?.currentUser else {
return
}
let query = FIRDatabase.database().reference(withPath :"driveways").queryEqual(toValue: currentUser.email!, childKey: "email")
query.observe(.value, with: { (snapshot) in
print(snapshot)
})
How can I get all the driveways based on user's email address?
Try this (Swift 3 Firebase 3)
let email = "johndoe#gmail.com"
let queryRef = drivewaysRef.queryOrdered(byChild: "email")
.queryEqual(toValue: email)
queryRef.observeSingleEvent(of: .value, with: { snapshot in
for snap in snapshot.children {
let driveSnap = snap as! FIRDataSnapshot
let driveDict = driveSnap.value as! [String:AnyObject] //driveway child data
let city = driveDict["city"] as! String
let state = driveDict["state"] as! String
print("email: \(email) city: \(city) state: \(state)")
}
})
Related
I'm working on a follow friends view controller that loads all the usernames in the database, BUT I don't want it to load the current user's username. I need to access the username from the currentUser's uid, and add all the usernames that are not equal to it to my array.
#objc func loadData() {
let rootRef = Database.database().reference()
let query = rootRef.child("users").queryOrdered(byChild: "username")
query.observeSingleEvent(of: .value) {
(snapshot) in
for child in snapshot.children.allObjects as! [DataSnapshot] {
let value = child.value as? NSDictionary
let username = value?["username"] as? String ?? ""
if username != rootRef.child(Auth.auth().currentUser!.uid).value(forKey: "username") as! String{
self.usernames.append(username)
}
print(username)
}
self.tableView.reloadData()
print(self.usernames)
}
}
You should try and minimise queries inside loops, especially irrelevent ones. Given your database schema uses the users unique id as the key, you can run your evaluation based on that key using child.key.
#objc func loadData() {
let rootRef = Database.database().reference()
let query = rootRef.child("users").queryOrdered(byChild: "username")
query.observeSingleEvent(of: .value) { (snapshot) in
for child in snapshot.children.allObjects as! [DataSnapshot] {
let value = child.value as? NSDictionary
let username = value?["username"] as? String ?? ""
if Auth.auth().currentUser!.uid != child.key {
self.usernames.append(username)
}
print(username)
}
self.tableView.reloadData()
print(self.usernames)
}
}
I am trying to iterate over all keys under "Timetable" to get the key value and Name of those that have an approved value of "Yes".
So for the following JSON structure:
Timetable
Pikes_Lane_Primary_School_Bolton_UK
Approved: Yes
Name: Pikes Lane Primary School
Essa_Academy_Bolton_UK
Approved: No
Name: Essa Academy
Ladybridge_High_School_Bolton_UK
Approved: Yes
Name: Ladybridge High School
My desired output would be:
Pikes_Lane_Primary_School_Bolton_UK
Pikes Lane Primary School
Ladybridge_High_School_Bolton_UK
Ladybridge High School
This is the best I've managed to do over the last few hours:
let schoolDatabase = Database.database().reference().child("Timetable")
schoolDatabase.observeSingleEvent(of: .value, with: { (snapshot) in
for child in snapshot.children {
let schoolID = child as! DataSnapshot
//print(schoolID.key)
for grandchild in schoolID.children {
let varOne = grandchild as! DataSnapshot
print(varOne.key)
}
}
})
This brings back the following:
Approved
Name
Approved
Name
Approved
Name
let schoolDatabase = Database.database().reference().child("Timetable")
schoolDatabase
.queryOrdered(byChild: "Approved")
.queryEqual(toValue: "Yes")
.observeSingleEvent(of: .value, with: { (snapshot) in
let children = snapshot.children
.compactMap { $0 as? DataSnapshot }
children.forEach { tuple in
print(tuple.key)
if let tupleDictionary = tuple.value as? [String: Any] {
let name = tupleDictionary["Name"] as? String
print(name ?? "-")
}
}
}
)
Or if you are interested only in names (without key):
let schoolDatabase = Database.database().reference().child("Timetable")
schoolDatabase
.queryOrdered(byChild: "Approved")
.queryEqual(toValue: "Yes")
.observeSingleEvent(of: .value, with: { (snapshot) in
let children = snapshot.children
.compactMap { $0 as? DataSnapshot }
.compactMap { $0?.value as? [String: Any]}
.compactMap { $0["Name"] as? String }
children.forEach { name in
print(name)
}
}
)
Finally got there in the end!
let schoolDatabase = Database.database().reference().child("Timetable")
schoolDatabase.observeSingleEvent(of: .value, with: { (snapshot) in
for child in snapshot.children {
let schoolID = child as! DataSnapshot
let stringApproved = schoolID.childSnapshot(forPath: "Approved").value
let stringSchoolName = schoolID.childSnapshot(forPath: "Name").value
if stringApproved as? String == "Yes" {
print(schoolID.key)
print((stringSchoolName)!)
print((stringApproved)!)
}
}
})
In my Firebase Realtime Database, I have a node labelled "groups" and this is how I constructed it:
Underneath the "users" above, I'm trying to use those userIds to reference the data within each user. This is how I constructed each "users" node I'm trying to reference:
In the below code snippet, I get the userIds from a snapshot of the groups' users child node. And then I run a for-in loop on those userIds to access the information in the "users" node.
The print("This should be the individual userId: ", userId) statement prints out each userId correctly. And the userRef.observeSingleEvent(of: .value, with: { (snapshot) in gets called the first time the for-in loop is called, but it's almost like it's ignored. The app crashes because the user array comes up empty at the end. However, a ridiculous amount of empty users show up in the array (when looking at the Variables View in the Debug Area). So, i feel like I'm running some form of a redundant loop or something.
guard let groupChatPartnerId = message.chatPartnerId() else {
return
}
var users: [User]?
let ref = Database.database().reference().child("groups").child(groupChatPartnerId)
ref.observeSingleEvent(of: .value, with: { (snapshot) in
let groupId = snapshot.key
let groupName = snapshot.childSnapshot(forPath: "groupName").value as! String
let userIdDictionary = snapshot.childSnapshot(forPath: "users").value as! Dictionary<String,AnyObject>
let userIds = Array(userIdDictionary.keys)
print("userIds: ", userIds)
for userId in userIds {
print("This should be the individual userId: ", userId)
let userRef = Database.database().reference().child("users").child(userId)
userRef.observeSingleEvent(of: .value, with: { (snapshot) in
print("This is the snapshot: ", snapshot)
let email: String = snapshot.childSnapshot(forPath: "email").value as! String
print("user's email: ", email)
let uid = snapshot.key
let username = snapshot.childSnapshot(forPath: "username").value as! String
let profileImageUrl = snapshot.childSnapshot(forPath: "profileImageUrl").value as! String
let user = User(uid: uid, userUsername: username, userProfileImageUrl: profileImageUrl, userEmail: email)
users?.append(user)
print("user to append to users: ", user)
}, withCancel: nil)
}
print("users :", users)
let group = Group(groupId: groupId, groupName: groupName, users: users!)
self.showChatControllerForGroup(group: group)
}, withCancel: nil)
Let me know if you need any other information. Thanks in advance!
All data is loaded from Firebase asynchronously By the time your print users, none of the userRef.observeSingleEvent has completed yet. So the code to print all users must be inside the completion handle of userRef.observeSingleEvent and must only run once all users have been loaded.
A simple way to do that is to compare the length of users with the length of userIds. If they're the same, you've loaded all users:
for userId in userIds {
print("This should be the individual userId: ", userId)
let userRef = Database.database().reference().child("users").child(userId)
userRef.observeSingleEvent(of: .value, with: { (snapshot) in
print("This is the snapshot: ", snapshot)
let email: String = snapshot.childSnapshot(forPath: "email").value as! String
print("user's email: ", email)
let uid = snapshot.key
let username = snapshot.childSnapshot(forPath: "username").value as! String
let profileImageUrl = snapshot.childSnapshot(forPath: "profileImageUrl").value as! String
let user = User(uid: uid, userUsername: username, userProfileImageUrl: profileImageUrl, userEmail: email)
users?.append(user)
print("user to append to users: ", user)
if userIds.count == users.count {
print("users :", users)
}
}, withCancel: nil)
}
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
}
})
i was making a Firebase practice app and i encountered this problem. Where i got NSNull exception while capturing a value from Firebase database. Here is the code
user = FIRAuth.auth()?.currentUser
ref = FIRDatabase.database().reference()
let userid = user.uid
if userid != nil
{
print("User Nid \(userid)")
ref.child("users").child(userid).observe(.value, with: {
(snapshot) in
if(snapshot.exists()){
var user_details = snapshot.childSnapshot(forPath: "\(userid)")
var user_det = user_details.value as! Dictionary<String, String>
print("User Name \(user_det["name"])")
}
else{
print("Does not exist")
}
})
}
and here is the database.
uid
user-details
name: "Salman"
propic: "picurl"
Could you try with this way
ref.child("users").child(userID!).observeSingleEvent(of: .value, with: { (snapshot) in
// Get user value
let value = snapshot.value as? NSDictionary
if let userDetail= value?["user-details"] as? [String:Any] {
// let username = value?["name"] as? String ?? ""
let username = userDetail["name"] as? String ?? ""
}
}) { (error) in
print(error.localizedDescription)
}