Is it possible to get database reference without childByAutoId (). Key? - swift

Is there a way to dynamically get a child database from the parent instance, without having to use childByAutoId () ?
{
"artists" : {
"artists_id_1" : {
"name" : "Atif Aslam",
"genre" : "Rock"
},
"artists_id_2" : {
"name" : "Arijit Singh",
"genre" : "Rock"
}
}
}
we usually refer to the path, and listener the items the DataBase...Example:
Database.database().reference().child("artists").child("artist_id_1").observeSingleEvent(of: .value, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject] {
print("\(String(describing: dictionary["name"] as? String))")
}
}, withCancel: nil)
it would only work for the first item. Because, it would not be dynamic. What is normally used is the following example below ...
{
"artists" : {
"-KeZUDrJv555kteAcssL-" : {
"name" : "Atif Aslam",
"genre" : "Rock"
},
"-KeZUVXFIQdO7JiyRYk-" : {
"name" : "Arijit Singh",
"genre" : "Rock"
}
}
}
Database.database().reference().child("artists").childByAutoId().observeSingleEvent(of: .value, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject] {
print("\(String(describing: dictionary["name"] as? String))")
}
}, withCancel: nil)
Anyway, I do not know if it was clear, anything can comment before answering. Thank you

To display all artists in your database, load the artists node and loop over snapshot.children:
Database.database().reference().child("artists").observe(.value) { (snap:DataSnapshot) in
for child in snapshot.children {
print(child.key)
}
}
For this and more examples, I recommend reading the Firebase documentation, specifically the section on reading and writing lists.

I dont know if i understand your question correctly or what you are trying to do but maybe you can try
Database.database().reference().child("artists").observe(.value) { (snap:DataSnapshot) in
// This should print out your childIds
print(snap.key)
// This should print out the values after them
print(snap.value)
}

Related

Counting Records In Swift From Firebase With A Where Statement

I am trying to return the count of posts for a specific user where a field contains a certain value. The structure I am using in Firebase is here:
{
"posts" : {
"-Lyzpsb1hH4LUPvcXE3H" : {
"beverageCategory" : "Beer",
"beverageName" : "Dortmunder",
"beveragePrice" : "3.99",
"beverageRating" : 3,
"beverageType" : "Lager",
"imageUrl" : "https://firebasestorage.googleapis.com/v0/b/socialspirit-37cae.appspot.com/o/post-pics%2F3C23E923-A3BD-4393-B3EF-8F939D8B08B8?alt=media&token=ac80cb98-f2a1-4197-b328-2a69a2ac1fd1",
"wineVintage" : ""
}
},
"user" : "sdkjvksdjf",
"users" : {
"0hyN8N2klJWqPi2lkRqNK3vg7z63" : {
"posts" : {
"-Ly6ciYHm7v5JFy1VmVY" : true,
"-Ly6cyLukI6aRRki5yna" : true
},
"provider" : "Firebase"
},
"26OUuaRZEVWUmkLJp13LzirGbs13" : {
"posts" : {
"-Ly6fGmQEMZz3c-azMnJ" : true
},
"provider" : "Firebase"
},
"5r6FulsvIRap7pLK5D3zV8qyPVv1" : {
"provider" : "Firebase"
},
"gQpktBMh97hTqiysHBwvVLZl70y1" : {
"posts" : {
"-Lyzpsb1hH4LUPvcXE3H" : true,
"-LyzqFgvmrBgdsgKSt_5" : true,
"-Lz-fIMDal00ex3_viQo" : true,
"-Lz-lXsSBqKlcf8hBext" : true,
"-Lz2eNLfk1PFEVkEgmwa" : true,
"-Lz2etF0UqFqLkdGOR13" : true,
"-Lz2fGUi0qzJtniNr5LX" : true,
"-Lz2gP5c47yHDO2g0ljr" : true,
"-Lz2gdhfedZfTtzjP2ee" : true,
"-Lz2gllC3caXgPf2VAPU" : true,
"-Lz2hH8FbNmBEOLcHCJz" : true,
"-Lz2jzkXuEZ3Cfe96eGW" : true,
"-Lz3RvuW4fMXarhW7vLv" : true,
"-Lz3S8YA0vgk4ZrjL_Kk" : true
},
"provider" : "Firebase"
}
}
}
I am using the following code to get the count of records that have a beverageCategory of "Beer".
DataService.ds.REF_USERS.child("\(uid)").child("posts").child("beverageCategory")
.queryOrderedByValue().queryEqual(toValue: "Beer")
.observe(DataEventType.value, with: { (snapshot) in
print("SNAP - \(snapshot.childrenCount)")
})
The childrenCount returns 0, however. Any idea what I'm doing wrong here? Thanks!
EDIT: I added the JSON for the data structure and I think I left an important detail out. The data structure actually has users that have posts and the associated postid that links back to posts. I think what I have to do is first find the user's posts and then of those posts get a total count for each category. I'm guessing that is slightly different than the methods I tried. Any ideas on that?
EDIT 2: So my issues is that users and posts are in different structures. I need to find all of the user's posts and iterate through them to see if what the beverageCategory is. I have done that with the following code. The issue with the code below is that the count is doubled when I add a post and then open the menu. But when I exit the menu and re-open the count is correct. Why is it double-counting?
func myFirebaseNetworkDataRequest(finished: #escaping () -> Void) {
beerCountArray.removeAll()
wineCountArray.removeAll()
liquorCountArray.removeAll()
print("BEER ARRAY \(beerCountArray.count)")
guard let uid = Auth.auth().currentUser?.uid else {
return
}
let newPost = DataService.ds.REF_USERS.child("\(uid)").child("posts")
newPost.observe(.value, with: { (snapshot) in
if let snapshot = snapshot.children.allObjects as? [DataSnapshot] {
//print("SNAPSHOT - \(snapshot)")
for snap in snapshot {
let postData = DataService.ds.REF_POSTS.child(snap.key)
//print("SNAP KEY - \(snap.key)")
let bevCat = DataService.ds.REF_POSTS.child(snap.key).child("beverageCategory")
//print("BEV CAT - \(bevCat)")
postData.observe(.value, with: { (snapshot) in
if let postDict = snapshot.value as? Dictionary<String, AnyObject> {
let key = snapshot.key
let post = Post(postKey: key, postData: postDict)
//print("POST DICT - \(String(describing: postDict["beverageCategory"]!))")
if postDict["beverageCategory"]! as! String == "Beer" {
self.beerCountArray.append(1)
//print("BEER ARRAY LOOP - \(self.beerCountArray)")
}
if postDict["beverageCategory"]! as! String == "Wine"{
self.wineCountArray.append(1)
}
if postDict["beverageCategory"]! as! String == "Liquor" {
self.liquorCountArray.append(1)
}
//self.posts.append(post)
}
finished()
})
}
}
})
}
And...
override func viewDidLoad() {
super.viewDidLoad()
beerCountArray.removeAll()
wineCountArray.removeAll()
liquorCountArray.removeAll()
myFirebaseNetworkDataRequest {
//print("BEER ARRAY - \(self.beerCountArray.count)")
self.beerCount.text = String(self.beerCountArray.count)
self.liquorCount.text = String(self.liquorCountArray.count)
self.wineCount.text = String(self.wineCountArray.count)
}
}
Your query is not correct. Since you're trying to filter on a child property of each node under posts, you should call queryOrdered(byChild:).
So:
DataService.ds.REF_USERS.child("posts")
.queryOrdered(byChild: "beverageCategory")
.queryEqual(toValue: "Beer")
.observe(DataEventType.value, with: { (snapshot) in
print("SNAP - \(snapshot.childrenCount)")
})
Also see the Firebase documentation on ordering and filtering data.

Get child nodes from firebase (Swift)

How can i get child nodes from firebase?
Firebase struct is here:
Me need to get a child "Photos" for each child above. And later add to collectionView each child "Photo".
My firebase struct:
{
"Студии" : {
"Бабулька" : {
"Photo" : {
"image" : "https://firebasestorage.googleapis.com/v0/b/test2-29e4b.appspot.com/o/city3.jpg?alt=media&token=12a87c0c-ade1-43f9-b76b-ecdaa86cf185"
},
"address" : "Сатурн",
"image" : "https://firebasestorage.googleapis.com/v0/b/test2-29e4b.appspot.com/o/city3.jpg?alt=media&token=12a87c0c-ade1-43f9-b76b-ecdaa86cf185",
"image1" : "https://firebasestorage.googleapis.com/v0/b/test2-29e4b.appspot.com/o/city3.jpg?alt=media&token=12a87c0c-ade1-43f9-b76b-ecdaa86cf185",
"name" : "Карапулька"
},
"Дубаи" : {
"Photo" : {
"image" : "https://firebasestorage.googleapis.com/v0/b/test2-29e4b.appspot.com/o/city1.jpg?alt=media&token=c442fd8f-4cc4-4e30-8242-975aaf5427dc"
},
"address" : "Тутушка",
"image" : "https://firebasestorage.googleapis.com/v0/b/test2-29e4b.appspot.com/o/city1.jpg?alt=media&token=c442fd8f-4cc4-4e30-8242-975aaf5427dc",
"name" : "Дубаи"
},
"Лондон" : {
"Photo" : {
"image" : "https://firebasestorage.googleapis.com/v0/b/test2-29e4b.appspot.com/o/oko1.jpg?alt=media&token=fedea2cb-93b1-496c-9392-0b95f4ada7b5"
},
"address" : "Бейкер стрит",
"image" : "https://firebasestorage.googleapis.com/v0/b/test2-29e4b.appspot.com/o/oko1.jpg?alt=media&token=fedea2cb-93b1-496c-9392-0b95f4ada7b5",
"name" : "Лондон"
}
}
}
Thanks for help.
To get to the data you want, iterate over all of the child notes of the main parent node. Assume the following structure
posts
post_0
Photo
image: "https://www....."
post_1
Photo
image: "https://www....."
and the code to get the image urls...
let ref = self.ref.child("posts")
ref.observeSingleEvent(of: .value, with: { snapshot in
for child in snapshot.children {
let snap = child as! DataSnapshot
let imageSnap = snap.childSnapshot(forPath: "Photo")
let dict = imageSnap.value as! [String: Any]
let url = dict["image"] as! String
print(url)
}
})

Trouble trying to retrieve data from Firebase

I have this piece of working code that saves data to Firebase:
let locRef = locationRef.childByAutoId()
let locItem = [
senderId : [
"location": getLocationID()
]
]
locRef.setValue(locItem)
And I want to retrieve the user's (identified by senderID) "location", so I tried this piece of code:
locationRef.child("location").child(senderId).observeSingleEventOfType(.Value, withBlock: { (snapshot) in
self.locationId = snapshot.value!["location"] as! String
}) { (error) in
print(error.localizedDescription)
}
However my app is crashing when the piece of code is run, and there are no errors. I think my mistake may be that .child("location") must be something else, but I do not know what.
Database structure (JSON):
{
"locations" : {
"-KLEdoj2eiF7EW9m0815" : {
"W6vSOHZLTwNM33JYqkKHvaIVRF13" : {
"location" : "Seattle, WA"
}
},
"-KLLfcOvYHwIufBALM0-" : {
"W6vSOHZLTwNM33JYqkKHvaIVRF13" : {
"location" : "London, United Kingdom"
}
},
Any help would be appreciated thanks!
You should be referring to your location as the following
FIRDatabase.database().reference().child("locations").child(locationId).child(senderId).observeSingleEventOfType(.Value, withBlock: { (snapshot) in
self.location = snapshot.value!["location"] as! String
}
For example:
If you have locationId = "-KLEdoj2eiF7EW9m0815" and senderId = "W6vSOHZLTwNM33JYqkKHvaIVRF13" the above call will set the self.location to "Seattle, WA"

Are there different solution how retrieve waypoints?

"-KHbCuQflKHrJiUmfpG0" : {
"waypoints" : {
"-KHbCuQflKHrJiUmfpG1" : {
"latitude" : 13.17078652595298,
"longitude" : -59.5775944578738
},
"-KHbCuQflKHrJiUmfpG2" : {
"latitude" : 13.15541190861343,
"longitude" : -59.57619643155932
},
"-KHbCuQg9W_tebl1pU66" : {
"latitude" : 13.148444967591,
"longitude" : -59.5589266947333
}
},
"subtitle" : "jamesrick",
"title" : "Highway",
"type" : "polyline"
},
I have this structure for lines in Firebase. How retrieve all data with also nested node waypoints?
ref.observeEventType(.Value, withBlock: { polylines in
if let objects = polylines.children.allObjects as? [FDataSnapshot] {
for object in objects {
polylineDictionary = object.values as? Dictionary<String, AnyObjects> {
// ? ? ?
}
}
}
})
Now I have access to title, subtitle, type but how obtain access to waypoints? When I use
`polylineDictionary["waypoints"] as? [String: [String:Double]]`
so this dictionaries are not ordered. Thanks for some advice.
This is how I would get the nested waypoints... it's basically by iterating through the keys... I would also add some error checking when grabbing the longitude and latitudes to make sure they're there, but this is the gist:
if let polylineDictionary["waypoints"] as? [String: [String:Double]] {
let waypoints = Array(polylineDictionary.keys)
for i in 0..<waypoints.count {
let waypointId = waypoints[i]
let latitude = polylineDictionary[waypointId]["latitude"]
let longitutde = polylineDictionary[waypointId]["longitude"]
}
}
It's not clear from the question about ordering; if you just want to get to the waypoints, it's pretty straight forward:
Assume your complete Firebase structure is:
root_node
"-KHbCuQflKHrJiUmfpG0" : {
"waypoints" : {
"-KHbCuQflKHrJiUmfpG1" : {
"latitude" : 13.17078652595298,
"longitude" : -59.5775944578738
},
"-KHbCuQflKHrJiUmfpG2" : {
"latitude" : 13.15541190861343,
"longitude" : -59.57619643155932
},
"-KHbCuQg9W_tebl1pU66" : {
"latitude" : 13.148444967591,
"longitude" : -59.5589266947333
}
},
"subtitle" : "jamesrick",
"title" : "Highway",
"type" : "polyline"
}
Suppose I want the data for this specific node, -KHbCuQflKHrJiUmfpG0
let nodeRef = rootRef.childByAppendingPath("-KHbCuQflKHrJiUmfpG0")
nodeRef.observeSingleEventOfType(.Value , withBlock: { snapshot in
print(snapshot.value) //prints everything in the node
let title = snapshot.value["title"] as! String //to get any element
print(title) //prints Highway
var waypoints = [String: [String:String]]() //dict to hold key:value, unordered
waypoints = snapshot.value["waypoints"] as! Dictionary
print(waypoints) //prints the 3 waypoints and their children (as a dict)
//get fancy and convert the dictionary to an array (which can be sorted)
let arr = waypoints.map {"\($0) \($1)"}
for point in arr {
print(point)
}
}

Swift & Firebase | Checking if a user exists with a username

I am trying to allow users to start games with and follow other users by searching their username. I need to be able to make sure that a user with that username exists. I was using the following code but although the if is called the else does not get called when it should.
let checkWaitingRef = Firebase(url:"https://test.firebaseio.com/users")
checkWaitingRef.queryOrderedByChild("username").queryEqualToValue("\(username!)")
.observeEventType(.ChildAdded, withBlock: { snapshot in
if snapshot.value.valueForKey("username")! as! String == username! {
} else {
}
JSON data tree
{
"097ca4a4-563f-4867ghj0-6209288bd7f02" : {
"email" : "test1#tes1.com",
"uid" : "097ca4a4-563f-4867ghj0-6209288bd7f02",
"username" : "test1",
"waiting" : "0"
},
"55a8f979-ad0d-438u989u69-aa4a-45adb16175e7" : {
"email" : "test2#test2.com",
"uid" : "55a8f979-ad0d-438u989u69-aa4a-45adb16175e7",
"username" : "test2",
"waiting" : "0"
}
}
Easy fix:
Don't use .childAdded as the block will not execute when the query doesn't find anything.
Instead use .Value and check for NSNull
let checkWaitingRef = Firebase(url:"https://test.firebaseio.com/users")
checkWaitingRef.queryOrderedByChild("username").queryEqualToValue("\(username!)")
.observeEventType(.Value, withBlock: { snapshot in
if ( snapshot.value is NSNull ) {
print("not found)")
} else {
print(snapshot.value)
}
})