I need help getting nested data in Firebase.
Here is how my data is structured in Firebase:
- Meetups
- UniqueID
- address: "xxxx"
- date: "xxxx"
- creator: "xxxx"
- invitedFriends
- 1: "xxxx"
- 2: "xxxx"
- 3: "xxxx"
I am trying to figure out how to retrieve the invitedFriends data.
Currently I retrieve the data this way:
BASE_URL.child("meetups").observeEventType(.Value, withBlock: { snapshot in
self.meetups = []
if let snapshots = snapshot.children.allObjects as? [FIRDataSnapshot] {
for snap in snapshots {
if let postDictionary = snap.value as? Dictionary<String, AnyObject> {
let key = snap.key
let meetup = Meetup(key: key, dictionary: postDictionary)
self.meetups.insert(meetup, atIndex: 0)
}
}
This allows me to create an instance of my Meetup class from the address, date, and creator. However, I recently added the invitedFriends data to the structure and I am trying to figure out how to query it in this same process. Thank you for any suggestions!
Modify your for loop this way:-
if let snapDict = snapshot.value as? NSMutableDictionary{
for snap in snapDict{
let user_ID = snap.key
Base
BASE_URL.child("meetups").child(user_ID).child("invitedFriends").observeEventType(.Value, withBlock: { snapshot in
if snapshot.exists(){
for invitees in snapshot.Value{
let invitedFrnds = invitees.Value
//Retrieving the friends.
//Rest of your code accordingly
}
}
})
}
}
Related
Im trying to retrieve a specific node in all my children and want to collect all the "role" in every child under "Users"
Here is the database setup:
Users:
25TWFD7SLmQ3onRUdffvfx6Nfmw1:
role: "officer"
9OwM6FIPZgOKu3zzVYSrkPWR0Ij2
role: "advisor"
How can I retrieve all of the "role" nodes?
here you can get the particular node "role".
//To get the all record
let ref = Database.database().reference()
ref.child("Users").childByAutoId().queryOrdered(byChild: "role").observeSingleEvent(of: .value) { (snapshot) in
//To check the data
guard let userDict = snapshot.value as? [String:Any] else {
return
}
let keyArray = [String] (userDict.keys)
for key in keyArray {
if var dataDict = userDict[key] as? [String:Any] {
self.userRoleArray.append(dataDict)
}
}
}
Hopefully this will work for you.
happy coding...
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
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.
}
}
})
I was wondering if anyone had any ideas on how to query multiple strings from an array at once in 'Firebase'. Basically query like you would using an AND condition. I have looked into restructuring my data in a hundred different ways but nothing has worked for me. Also, I have too much data to dump all the data and then match to my array after the query is performed. Any help or suggestions are greatly appreciated.
var uniqueStoreId = [“1”, “2”, “3”, “4”, “5”, “6”]
var posts = [Post]()
ref.queryOrderedByChild("storeId").queryEqualToValue("\(uniqueStoreId)").observeEventType(.Value, withBlock: {snapshot in
if let snapshot = snapshot.children.allObjects as? [FIRDataSnapshot] {
for snap in snapshot{
if let postDict = snap.value as? Dictionary<String, AnyObject> {
let key = snap.key
let post = Post(postKey: key, postData: postDict)
self.posts.insert(post, atIndex: 0)
}
}
}
})
// do something like this, check whether its array or dictioary, then add in one array and then use as per requirement.. enjoy
var arrMessage = [MessageFirebase]()
if let snapshots = snapshot.children.allObjects as? [FIRDataSnapshot] {
//If its a Array then use below method
for snap in snapshots {
if let postDictionary = snap.value as? Dictionary<String, AnyObject> {
let key = snap.key
let message = MessageFirebase(key: key, dictionary: postDictionary)
// Items are returned chronologically, but it's more fun with the newest jokes first.
//if needed
arrMessage.insert(message, atIndex: 0)
}
}
//If its a dictionary then use below method
if !(arrMessage.count > 0) {
let key = snapshot.key
let message = MessageFirebase(key: key, dictionary: snapshot.value!)
// Items are returned chronologically, but it's more fun with the newest jokes first.
//if needed
arrMessage.insert(message, atIndex: 0)
}
}
I have a "flatened" Firebase structure and trying to retrieve a dictionary of values from a "secondary" database member. In other words, I have a conversation which has a "to" cell which has the key to a business listing. With this key, I'm trying to retrieve the business listing and its children (url, description, title). For some reason, I can print the snapshot2.value and it responds with the expected value, but I can't pass it to my class initialization.
DataService.ds.REF_CONVOS.observeEventType(.Value, withBlock: {snapshot in
self.convoListings.removeAll()
self.convoListings = []
//Data parsing from Firebase. The goal is to breakdown the data received and store in a local model.
if let snapshots = snapshot.children.allObjects as? [FDataSnapshot] {
for snap in snapshots {
for convo in userConvos {
// Going into the children of the main object for the conversations.
//print("\(snap)")
if convo == snap.key {
//print(snap.value)
print(snap.value)
if let businessDict = snap.value as? Dictionary<String, AnyObject> {
businessName.removeAll()
let test = businessDict["to"] as? String
DataService.ds.REF_BusinessListing.childByAppendingPath(test).childByAppendingPath("title/").observeSingleEventOfType(.Value, withBlock: { snapshot2 in
print(snapshot2.value)
})
let key = snap.key
let post = ConvoListing(convoKey: key, dictionary: businessDict, businessName: self.test2)
self.convoListings.append(post)
}
}
}
}
}
self.tableView.reloadData()
})
Your nesting seems of:
DataService.ds.REF_BusinessListing.childByAppendingPath(test).childByAppendingPath("title/").observeSingleEventOfType(.Value, withBlock: { snapshot2 in
print(snapshot2.value)
})
let key = snap.key
let post = ConvoListing(convoKey: key, dictionary: businessDict, businessName: self.test2)
self.convoListings.append(post)
Keep in mind the observeSingleEventOfType loads the data asynchronously. For this reason, if you have code that needs the value that you loaded, you need to put that code in the block:
DataService.ds.REF_BusinessListing.childByAppendingPath(test).childByAppendingPath("title/").observeSingleEventOfType(.Value, withBlock: { snapshot2 in
print(snapshot2.value)
let key = snap.key
let post = ConvoListing(convoKey: key, dictionary: businessDict, businessName: self.test2)
self.convoListings.append(post)
})