Getting all data in a Firebase column - ios

I created JSON database tree and I can read specific values with these codes. I can see on table view "Albert Einstein"
ref.child("Personel").child("Name").observeSingleEvent(of: .value, with: { (snapshot) in
if let item = snapshot.value as? String{
self.myList.append(item)
self.LessonsTableView.reloadData()
}
})
But, I want to see which categories under Personal column? Like this,
Is there any way to get or learn which columns are under "Personal"
Table view output must be -> Age, Name, Photo

You can iterate over the snapshot, get it's children and then those childrens keys
Say you have a users node with a user
users
user_0
fav_game: "WoW"
name: "Leroy"
then to get the keys of name: and fav_game:
let userRef = self.ref.child("users").child("user_0")
userRef.observeSingleEvent(of: .value, with: { snapshot in
for child in snapshot.children {
let snap = child as! DataSnapshot
let key = snap.key
print(key)
}
})
prints
fav_game
name
An important note is
for child in snapshot.children
because that will keep the data (keys in this case) in order. If the snapshot is dumped into a dictionary it looses order.

If you loop through snapshot.value you should be able to get the keys from the database.
In JavaScript it would be something like:
ref.child("Personel").child("Name").observeSingleEvent(of: .value, with: { (snapshot) in
if let item = snapshot.value as? String{
self.myList.append(item)
self.LessonsTableView.reloadData()
}
var vals = snapshot.val();
for(var property in vals) {
console.log(property); // property has those values in it
}
})

This is one way:
ref.child("Personel").observeSingleEvent(of: .value, with: { (snapshot) in
self.myList.append(snapshot.childSnapshot(forPath: "Age").value)
self.myList.append(snapshot.childSnapshot(forPath: "Name").value)
self.myList.append(snapshot.childSnapshot(forPath: "Photo").value)
self.LessonsTableView.reloadData()
})

Related

Fetch first key from firebase database with swift 4 using ChildAdded

I'm trying to fetch the first key from my firebase database but for some reason nothing is being printed out. How can I get the first key from my firebase database using .childAdded
let userMessagesRef = Database.database().reference().child("user-message").child(uid).child(userId)
userMessagesRef.observe(.childAdded, with: { (snapshot) in
guard let first = snapshot.children.allObjects.first as? DataSnapshot else { return }
print(first)
This in incredibly easy if you literally are asking how to only ever get the first child of a node. Here's how to only get the first child of a /users node
func getFirstChild() {
let usersRef = self.ref.child("users")
usersRef.observeSingleEvent(of: .childAdded, with: { snapshot in
print(snapshot)
})
}
or
print(snapshot.key)
if you just want the key.
Or, if you want to use a query to do the same thing
func getFirstChildAgain() {
let usersRef = self.ref.child("users")
let query = usersRef.queryOrderedByKey().queryLimited(toFirst: 1)
query.observeSingleEvent(of: .value, with: { snapshot in
print(snapshot)
})
}
The child_added event is typically used when retrieving a list of items from the database. Unlike value which returns the entire contents of the location, child_added is triggered once for each existing child and then again every time a new child is added to the specified path. The event callback is passed a snapshot containing the new child's data. For ordering purposes, it is also passed a second argument containing the key of the previous child.
From: Read and Write Data on iOS
Per your requirements, this is possible in .value and childAdded.
var child_array = [String:String]
let userMessagesRef = Database.database().reference().child("user-message").child(uid).child(userId)
userMessagesRef.observe(.childAdded, with: { (snapshot) in
let value = snapshot.value as? String ?? "Empty String"
let key = snapshot.key
child_array[key] = value;
}) { (error) in
print(error.localizedDescription)
}
then:
if let first = child_array.first?.key {
print(first) // First Key
}
Big NOTE: child_added randomly collects this data, you should never use it to sort your data

How to retrieve data from different DatabaseReference at same time

I have places in different cities in my real time database (firebase).
Following is my database structure.
But according to firebase tutorial, I tried following code to get data
cityA.queryOrdered(byChild: "completed").observe(.value, with: { snapShot in
var newItems: [AttractionPlace] = []
for child in snapShot.children {
if let snapShot = child as? DataSnapshot,
let attraction = AttractionPlace(snapShot: snapShot) {
newItems.append(attraction)
}
}
print(newItems.count)
})
I also would like to get data from cityB at the SAME TIME and no idea how to retrieve. I know I can repeat same action to cityB. But is there any better way?
I'm not sure how you want your data structured. Can you show me what an AttractionPlace is supposed to look like? The code below does what you want appending the name of each place to newItems, but without specifying from which city it is. Take notice that I did not use your AttractionPlace object.
let dataref = Database.database().reference()
dataref.child("attractions").observe(.value, with: { (snapshot) in
var newItems = [AnyObject]()
for city in snapshot.children.allObjects as! [DataSnapshot] {
let value = city.value as? NSDictionary ?? [:]
for child in value {
let attraction = child.value
newItems.append(attraction as AnyObject)
}
}
print("newItems: ",newItems)
print("newItems.count: ",newItems.count)
})
Result:
newItems: [Place 3, Place 4, Place 1, Place 2]
newItems.count: 4

How to search for a specific key in firebase without having a reference to that key

My database structure looks like this:
Structure
My reference is initialized like this:
let databaseRef = FIRDatabase.database().reference().child("Butikker")
When i run this function in viewdidload, my console prints: nil nil
func fetchNearByPlaces() {
databaseRef.observeSingleEvent(of: FIRDataEventType.value, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject] {
print(dictionary["Longtitude"], dictionary["Latitude"])
}
})
I want to print all the values that has the key: Longtitude and Latitude without referring to a specific path.
When observing a node in Firebase by .childAdded, it returns each node, one at a time and the snapshot children can be accessed directly.
When observing by .value however, the snapshot contains the parent nodes and all of the children. In that case, to get at each child node, iterate over the snapshot like this:
let databaseRef = self.ref.child("Butikker")
databaseRef.observeSingleEvent(of: .value, with: { (snapshot) in
for child in snapshot.children {
let snap = child as! DataSnapshot
let dictionary = snap.value as! [String: Any]
print(dictionary["Longitude"], dictionary["Latitude"])
}
})
also, in Firebase 4, instead of FIRDataEventType.value, just use .value

Searching through child values Firebase / Swift

My database has values sorted like this :
Users
UID
Username
Email
I'm wanting to implement a friend adding system where you search for either a username or email and it lets you add the person.
I'm able to locate users by using
REF_USERS.queryOrdered(byChild: "displayname").queryEqual(toValue: input).observeSingleEvent(of: .value) { (snapshot: FIRDataSnapshot) in {
print(snapshot.value)
}
With that I get the user's entire dictionary, but I'm having an issue grabbing the UID.
snapshot.key gives me "Users".
How can I grab the UID value out of the dictionary after finding the user's dictionary with either their username/email?
Try this...
Assume a structure (this is Swift 2, Firebase 2)
users
uid_0
email: "someuser#thing.com"
displayName: "some display name"
and we want to get uid_0's info
let displayName = "some display name"
usersRef.queryOrdered(byChild: "displayName").queryEqual(toValue: displayName)
.observeSingleEvent(of: .childAdded) { (snapshot: FIRDataSnapshot) in {
let dict = snapshot?.value as! [String: AnyObject]
let email = dict["email"]
let displayName = dict["displayName"]
print(email!)
print(displayName!)
let key = snapshot?.key
print(key!)
}
A couple things to note
The 'dict' variable is being told it's being assigned a dictionary of type [String: Anyobject].
Any Object could well, be any object. A String, another dictionary, an int. So you need to ensure you code can handle whatever the object is
The snapshot key in this case is the snapshot of this user, and the key must be the parent node, which in this case is uid_0. So the output is
someuser#thing.com
some display name
uid_0
EDIT:
Updated for Firebase 4, Swift 4 and handle the case where multiple children are returned
let usersRef = self.ref.child("users")
let input = "some display name"
let query = usersRef.queryOrdered(byChild: "displayName").queryEqual(toValue: input)
query.observeSingleEvent(of: .value, with: { snapshot in
for child in snapshot.children {
let snap = child as! DataSnapshot
let dict = snap.value as! [String: Any]
let email = dict["email"] as! String
let displayName = dict["displayName"] as! String
print(email)
print(displayName)
let key = snapshot.key
print(key)
}
})
When you execute a query against the Firebase Database, there will potentially be multiple results. So the snapshot contains a list of those results. Even if there is only a single result, the snapshot will contain a list of one result.
let query = REF_USERS.queryOrdered(byChild: "displayname").queryEqual(toValue: input)
query.observeSingleEvent(of: .value) { (snapshot: FIRDataSnapshot) in {
for child in snapshot.children {
print(child.key)
}
}
Also see:
Firebase snapshot.key not returning actual key?
Firebase access keys in queryOrderBy
Firebase access keys in queryOrderBy
Firebase getting data in order

How to extract child of node in data snapshot

My firebase set up is as such:
Parent_node:{
Type:{
1476663471800:{ //This is a timestamp = Int64(date.timeIntervalSince1970 * 1000.0)
uid: USERS_UID;
}
}
}
how would I access the users uid? I have tried the following code, but its not extracting the UID
self.databaseRef.child("Parent_node/\(Type)").queryLimitedToLast(5).observeEventType(.Value, withBlock: { (snapshot) in
print(snapshot)
if let userDict = snapshot.value as? [String:AnyObject]{
for each in userDict{
let uidExtraced = each
print(uidExtraced)
//("1476663471700", [uid: USERS_UID])
First of all use snapshot.value?.allValues to get values and than parse it...
if snapshot.exists() {
for value in (snapshot.value?.allValues)!{
print(value) // you get [uid: USERS_UID] here
// ... parse it to get USERS_UID
print("user_id -- \(value["uid"])")
}
}
With this method, order of child might be different. For ordered nodes, you can use snapshot.child

Resources