Unable to node specific values in firebase using swift 3 - ios

I am able to fetch all users but I want need user ID specific data.
For example you can see here are lots of users are registered but I need details only for 3 nodes:
323QGP6qryTWs7EnnXRX1stgocP2
iy5ssz0ALphtgViALEOG0N4TeGd2
OlA0rhAVfsNvixe8KEsUmdCfuN42
Please help to get these records.
Thanks.

let ref = Database.database().reference().child("users").observeSingleEvent(of: .value, with : { snapshot in {
if snapshot is NSNull{
//handles errors
}
else{
let dict = snapshot.value as? NSDictionary{
let firstDict = dict["323QGP6qryTWs7EnnXRX1stgocP2"] as? NSDictionary
let secondDict = dict["iy5ssz0ALphtgViALEOG0N4TeGd2"] as? NSDictionary
let thirdDict = dict["OlA0rhAVfsNvixe8KEsUmdCfuN42"] as? NSDictionary
//Then to gather whichever node you want inside these users:
let requestedNode = THEDICTIONARYYOUARELOOKINGAT["THE_NAME_OF_THE_NODE"] as? String //String, Int, Dictionary, array, boolean, ect.
}
}
})

Related

Accessing Nested Children in Firebase Database Swift 3

My current firebase database structure is like this
customer
-L1x2AKUL_KNTKXyza
name:"abc"
subscription
-L1x2AKlvmG0RXv4gL
sub_no: "123"
sub_name: ""
-L1x2AKlvmG0RXv4ab
sub_no: "456"
sub_name" ""
-L1x2AKUL_KNTKXymk
name:"xyz"
subscription
-L1x2AKlvmG0RXv4xy
sub_no: "789"
sub_name: ""
I am trying to access all subcriptions of all customer records at once.
This is the code I am using:
var ref: DatabaseReference!
ref = Database.database().reference(withPath: "customer")
ref.observe(.value, with: { snapshot in
let enumerator = snapshot.children
while let rest = enumerator.nextObject() as? DataSnapshot {
let imageSnap = rest.childSnapshot(forPath: "subscription")
let dict = imageSnap.value as! NSDictionary
//self.vehicleListDict.append(dict.object(forKey: "sub_no") as! NSDictionary)
print("value : \(dict)")
}
print("vehicleListDict : \(self.vehicleListDict)")
}) { (error) in
print(error.localizedDescription)
}
I am unable to access all the subscriptions within all customer records at once. Its only accessing till one level. I tried to put a while loop within the while that exists but that also does not give me the output needed. It goes in an infinite loop instead. Please could anyone help. I am using firebase realtime database for the first time.
The fetched values should be
123
456
789
The code for doing specifically what you are asking is
let customerRef = self.ref.child("customer")
customerRef.observe(.childAdded, with: { snapshot in
let subscriptionSnap = snapshot.childSnapshot(forPath: "subscription")
for child in subscriptionSnap.children {
let snap = child as! DataSnapshot
let dict = snap.value as! [String: Any]
let subNo = dict["sub_no"] as! String
print(subNo)
}
})
and the output is
a123
a456
a789
*note that I am reading the sub_no as a STRING which is why I added 'a' in front. If they are actually integers change the line to
let subNo = dict["sub_no"] as! Integer
*note2 this will leave a .childAdded observer to the main node in question so any further children that are added will fire the code in the closure.
Edit:
If you want to just retrieve all of the data at one time and not leave a childAdded observer then this will do it:
let customerRef = self.ref.child("customer")
customerRef.observeSingleEvent(of: .value, with: { snapshot in
for customerChild in snapshot.children {
let childSnap = customerChild as! DataSnapshot
let subscriptionSnap = childSnap.childSnapshot(forPath: "subscription")
for subscriptionChild in subscriptionSnap.children {
let snap = subscriptionChild as! DataSnapshot
let dict = snap.value as! [String: Any]
let subNo = dict["sub_no"] as! String
print(subNo)
}
}
})
and the output is
a123
a456
a789

Reading data from firebase (ios)

I have a small dataset in Firebase database, but unfortunately, I can't get read value from list correctly. Here is the structure of the database.
I just need to get the value of day and reference it to var. Thanks in advance.
var collnum = ""
ref = Database.database().reference()
let collid = ref.child("collid").child("day")
collid.observeSingleEvent(of : .value, with : {(Snapshot) in
print(Snapshot)
if let snapDate = Snapshot.value as? String{
collnum = snapDate
print(snapDate)
}
})
let database = FIRDatabase.database().reference()
database.child("collid").queryOrderedByKey().observe(.value, with:
{
if let value = snapshot.value as? [String: AnyObject]
{
let ui = value["day"] as! String
print(ui)
}
}
You can do something like this to read the data. This will read the data from the database and put into an array, allowing you to read the data.

Fetch Firebase inside another fetch

So I am creating a forum inside my app and when fetching the topics on the database I also need to fetch some user info like picture and username of the original poster to put it on the table view cells.
To keep the recommendation of keeping the Firebase database flat I have the messages on a separate ref searchable by key and NOT as a child of topics.
I can't keep something like opImage and opUsername as childs of topics because if a user changes its username or profile image I would need to change it on every topic he ever participated as well.
What is the best way to handle this?
The method to fetch from Firebase would look something like this. The problem with that implementation is that the Firebase calls are asynchronous and there would be no guarantee that the image would be attached to the correct topic.
DataService.ds.Topics_Base.child(cat.key!).observeSingleEvent(of:.value, with: { (snapshot) in
if let snapshots = snapshot.children.allObjects as? [FIRDataSnapshot] {//snapshots = all topics
for top in snapshots{
if let dict = top.value as? Dictionary<String,AnyObject>{
guard let title = dict["title"] as? String,let text = dict["text"] as? String,let time = dict["time"] as? String,let username = dict["username"] as? String,let timeSimple = dict["time-simple"] as? String,let lastPost = dict["last-post"] as? String,let open = dict["open"] as? Bool else{
continue
}
let newTopic = Topic(subject: title, text: text, time: time, topicKey: top.key, username: username)
self.allTopics.append(newTopic)
print(self.allTopics.count)
if let email = dict["email"] as? String{
//FETCH USER INFO FROM EMAIL FETCHED
let validEmail = HelperMethods.removeSpecialCharactersFromEmail(email: email)
DataService.ds.Users_Base.child(validEmail).observeSingleEvent(of: .value, with: {(snapshot) in
if let userDict = snapshot.value as? Dictionary<String,AnyObject>{
if let imgUrl = userDict["profile_image_url"] as? String{
self.allTopics[currentIndex].opImageUrl = imgUrl
}
self.allTopics.append(newTopic)
if (totalTopics == snapshots.count){
DispatchQueue.main.async {
self.allTopics.sort { $0.lastPostTime! > $1.lastPostTime!}
self.tableView.reloadData()
self.refreshControl.endRefreshing()
}
}
}
})
}
} }
}
}
)
}
Thanks in advance.
I ended up deciding to fetch the user info AFTER fetching all topics and then looping through the topics array and attaching user info for each topic.
EXAMPLE:
1 - fetch all topics and create array
2 - for each topic in array{
fetch user on Firebase using a property like topic.email
set something like:
topic.imageUrl = user.imageUrl
topic.username = user.username
}
reload table view

Unable to get keys from firebase database

I have been pondering for the longest time in my student programmer life. I would like to know
I added the keys using autoChildId.
How to get keys from firebase database swift 2? I know how to get from Android using .getKeys()
My best friend, Google, taught me to use allKeys. However, my friendship is on the verge of in despair right now as I received the following msg that our relationship with .allKeys will always fail ( see image below). Haish...
I need this in order to show the data from Firebase Database into my tableview cos I believe this is the issue to a empty table just like how my heart is for my project. No heart.
Here is how my firebase database looks like:
Here is my code:
func findPlaceToEat(){
print("inside findPlaceToEat()")
print("Plan price level")
print(planPriceLevel)
print("End of price level")
ref = FIRDatabase.database().reference()
ref.child("places_detail").child("price_level").child(planPriceLevel).observeEventType(.ChildAdded, withBlock:{
(snapshot) in
if let dictionary = snapshot.value?.allKeys! as? [String: AnyObject]{
let PlaceObj = placeObj(place_name: dictionary["place_name"] as! String, place_type: dictionary["place_type"] as! String, price_range: dictionary["price_range"] as! String, vegan_type:dictionary["vegan_type"] as! String , website: dictionary["website"] as! String)
print("Whatever")
print(PlaceObj);
//self.tableView.reloadData()
}
}, withCancelBlock: nil)
}
to get key from snapshot
snapshot.key
I got a workaround for my project, everyone please pray that my lecturer don't see this. :
What I did was inside the save button I retrieve the value from database and then save it back into Firebase Database.
ref = FIRDatabase.database().reference()
ref.child("hello").child("google! I need a part time job").child(planPriceLevel).observeEventType(FIRDataEventType.ChildAdded, withBlock:{
(snapshot: FIRDataSnapshot) in
if let dictionary = snapshot.value as? [String: AnyObject]{
let getPlaceObj = placeObj()
getPlaceObj.setValuesForKeysWithDictionary(dictionary)
self.PlaceObj.append(getPlaceObj)
print("Name " ,getPlaceObj.place_name)
}
let place_name = snapshot.value?.objectForKey("place_name") as! String
let place_type = snapshot.value?.objectForKey("place_type") as! String
let price_range = snapshot.value?.objectForKey("price_range") as! String
let vegan_type = snapshot.value?.objectForKey("vegan_type") as! String
let website = snapshot.value?.objectForKey("website") as! String
print(place_name, place_type, price_range, vegan_type, website)
let savePlan : [String: AnyObject] = ["place_name":place_name, "place_type":place_type, "price_range":price_range, "vegan_type":vegan_type, "website":website]
self.ref.child("can you place hire me as your intern? I am from Singapore!!!").child(self.user!.uid).childByAutoId().setValue(savePlan)
}, withCancelBlock: nil)
You need to define query orderbykey like bellow:
this.afd.list('/yourItems/', {query:{orderByKey :true}}).subscribe((elements) => {
elements.map(element=>{
console.log(element.$key);
})
});

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.

Resources