How can i get only keys from firebase? - ios

I have a structure of database as on image and I need to display this date which is in the red rectangle. I tried to do smth like this, but it throws an error and I couldn't find same questions on a stack.
my database
reference.child("doc1").observe(.value, with: { (snapshot) in
if snapshot.exists() {
for date in (snapshot.value?.allKeys)
}

Your structure is a Dictionary of Dictionary so you have to cast your snap to [String:[String:Any]] where the key is your "11dot..." and value contains all hours
So try to use this code:
guard let dict = snap.value as? [String:[String:Any]] else { return }
for (key, value) in dict {
for (key2, value2) in value {
print(key2, value2) // this print your hours
}
}
Anyway I suggest you to don't use a observe(.value) which will read all change happened on all child node. Instead use the .childAdded feature of observer.
With a .childAdded you will receive only one child at a time (like a for on child node) and after that only the child added:
Database.database().reference().child("doc1").observe(.childAdded) { (snap) in
guard let dict = snap.value as? [String:Any]
print(dict) // this print data contains on "11dot10" and so on
}

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

Retrieving only string values from firebase

As you can see from the image above underlined in red, I have a child that has a String value along with an Int Value. Now is it possible to retrieve only the String value? At the moment I'm using the code below but it retrieves the string and Int values not just the string value. I can't seem to figure how to isolate the string value. Any help would greatly appreciated. Thanks
Database.database().reference().child("likes").child(self.userUID).observe(.value, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: Any]{
let uid = dictionary[""] as! String
print("uid")
}
})
Try this:
Database.database().reference().child("likes").child(self.userUID).observe(.value, with: { (snapshot) in
for child in snapshot.children {
let c = child as! FIRDataSnapshot
print(c.key)
}
})
Here your snapshot is the userid and then you add a for loop to iterate inside the children of the userid and get the key of those children in the print.
Example:
J2xb677oeCNhDMVW2WRwHeBzirM2

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

How to retrieve objects from firebase by key value

I'm new to firebase and I have such structure of my firebase project
I want to get all objects, that "Interested" value is equal to "men"
I wrote such code, to get all object sorted by interes value:
let thisUserRef = URL_BASE.childByAppendingPath("profile")
thisUserRef.queryOrderedByChild("Interest")
.observeEventType(.Value, withBlock: { snapshot in
if let UserInterest = snapshot.value!["Interest"] as? String {
print (snapshot.key)
}
}
But I receive nil.
you need to loop through all the key-value profiles
if let allProfiles = snapshot.value as? [String:AnyObject] {
for (_,profile) in allProfiles {
print(profile);
let userInterest = profile["Interest"]
}
}
Here _ is the key that is in the format KYXA-random string and profile will be the element for that key.
Edit:
There is querying for child values as per the docs.
Try thisUserRef.queryOrderedByChild("Interest").equalTo("men") and then using the inner loop that i specified in the answer
This is a basic query in Firebase. (Updated for Swift 3, Firebase 4)
let profileRef = self.ref.child("profile")
profileRef.queryOrdered(byChild: "Interest").queryEqual(toValue: "men")
profileRef.observeSingleEvent(of: .value, with: { snapshot in
for child in snapshot.children {
let dict = child as! [String: Any]
let name = dict["Name"] as! String
print(name)
}
})
The legacy documentation from Firebase really outlines how to work with queries: find it here
Legacy Firebase Queries
The new documentation is pretty thin.
Oh, just to point out the variable; thisUserNode should probably be profileRef as that's what you are actually query'ing.

Firebase with Swift ambiguous use of observeEventType

I've been pulling my hair out because of this. Going to all the pages with related incidents and multiple tutorials I find nothing wrong with my code here, but somehow it only doesn't fail if I print out the values (which works) or assign them as! NSArray which then gives me an empty array.
a print of snapshot.value shows
( friend1,
friend2,
friend3
)
I've tried snapshot.value.values ... no dice.
I've tried playing with the unwrapping ... no dice.
and this is my final attempt:
friendsList = [String]()
ref.observeSingleEventOfType(.Value) { (snapshot) -> Void in
if snapshot.value is NSNull {
} else {
for child in snapshot {
self.friendsList.append(child.value)
}
}
}
which gives me the ambiguous thing again.
Just some coding errors
Remove: (snapshot)-> Void
Change: child in snapshot as snapshot is not a sequence, whereas snapshot.children is
I assume you want to store the friends name as a string and name is a key in your structure. So change self.friendsList.append(child.value) to
let name = child.value["name"] as? String
friendsList.append(name!)
Here's the corrected code:
var friendsList = [String]()
ref.observeSingleEventOfType(.Value, withBlock: { snapshot in
if snapshot.value is NSNull {
} else {
for child in snapshot.children {
let name = child.value["name"] as? String
friendsList.append(name!)
}
print("\(friendsList)")
}
})
ref.observeSingleEvent(of: .value, with: { (snapshot) -> Void in
})
Work for me, Xcode 8.3.2

Resources