how parsing Firebase FDatasnapshot json data in swift
Firebase is a NoSQL JSON database and has no schema and no tables. Data is stored with a 'tree' structure with nodes; parents and children.
You don't need to parse Firebase JSON data to access it, you can access it directly.
FDataSnapshots contain a .key, which is it's parent key in Firebase and .value. .Value may contain one node, or multiple nodes. The Value will have key:value pairs representing the data within the snapshot
So for your example you will have a Firebase structure like this
dogs
dog_id_0
title: "dog"
type: "Alaskan Malamute"
images:
main: "dog.png"
others:
0: "1.png"
1: "2.png"
dog_id_1
title: "another dog"
type: "Boxer"
images:
main: "another_dog.png"
others:
0: "3.png"
1: "4.png"
So, say you want to read in each dog_id_x node one at a time and print some values.
var ref = Firebase(url:"https://your-app.firebaseio.com/dogs")
ref.observeEventType(.ChildAdded, withBlock: { snapshot in
println(snapshot.value.objectForKey("title"))
println(snapshot.value.objectForKey("type"))
})
This will output
dog
Alaskan Malamute
another dog
Boxer
The dog_id_0 and dog_id_1 are node names created with the Firebase childByAutoId.
You could just as easily create a Dog class, and pass it the FDataSnapshot which will populate the class from the data within the snapshot.
firebase json deserialization swift
Instead of trying to fix all of that code, here's a clean, simple way to populate an array of rooms, where each room has an array of users.
Given a Firebase Structure similar to yours
"rooms"
"room_0"
"groupChatName" : "Test123",
"members"
"user_0"
"name" : "Barry"
"user_1"
"name" : "Maurice"
"user_2"
"name" : "Robin"
We start off with the RoomClass and UserClass. Note that I make those classes do the heavy lifting - they tear down the snapshot and store it's values.
Note that I treat the members child node as a snapshot so I can iterate over it while maintaining it's key: value pairs.
class RoomClass {
var key = ""
var groupChatName = ""
var membersArray = [UserClass]()
init(snapshot: DataSnapshot) {
let dict = snapshot.value as! [String: Any]
let membersSnap = snapshot.childSnapshot(forPath: "members")
let snapKey = snapshot.key
let groupName = dict["groupChatName"] as! String
self.key = snapKey
self.groupChatName = groupName
for member in membersSnap.children {
let memberSnap = member as! DataSnapshot
let user = UserClass(snapshot: memberSnap)
self.membersArray.append(user)
}
}
}
class UserClass {
var key = ""
var name = ""
init(snapshot: DataSnapshot) {
let dict = snapshot.value as! [String: Any]
let snapKey = snapshot.key
let userName = dict["name"] as! String
self.key = snapKey
self.name = userName
}
}
We then define the array to store the rooms and the code to populate it
var roomsArray = [RoomClass]()
func doButton0Action() {
let roomsRef = self.ref.child("rooms")
roomsRef.observeSingleEvent(of: .value, with: { snapshot in
for child in snapshot.children {
let snap = child as! DataSnapshot
let room = RoomClass(snapshot: snap)
self.roomsArray.append(room)
}
//this just demonstrates the rooms and members are loaded
for room in self.roomsArray {
let groupChatName = room.groupChatName
print(groupChatName)
for user in room.membersArray {
let userName = user.name
print(" \(userName)")
}
}
})
}
and the output
Test123
Barry
Maurice
Robin
Trying to get data from firebase Swift
You are trying to return value out of completion handler.
Your function should be like:
private func findAverage(byUid uid: String, completion: @escaping (_ average: Int) -> Void) {
// ...
dbRef.observeSingleEvent(of: .value, with: { snapshot in
guard let dict = snapshot.value as? [String: Any] else {
return
}
totalRatings = dict["totalRatings"] as? Int ?? 0
amountOfRatings = dict["amountOfRatings"] as? Int ?? 1
completion((Int)(totalRatings / amountOfRatings))
})
}
Something like this, check Swift docs (about completion handlers etc.).
Can I manipulate FDatasnapshot once I have queried for it?
Firebase accepts all the data in JSON
format only. When you get a Datasnapshot
of any perticular node of Firebase, you get the complete data below that node, which is in all a JSON only.
Once you get the Datasnapshot JSON
you can parse it using any JSON
library, depending on the platform you use.
You can refer here Datasnapshot Methods for more info.
What kind of object is the following output?
It's an FDataSnapshot
. Since Firebase is a NoSQL/JSON data store, it serializes these snapshots to a pseudo-JSON structure when you print them. But when you need to get primitive values out of a snapshot, use the methods of FDataSnapshot
like childSnapshotForPath:
until you reach a simple property (FirstName
and LastName
in your sample) and then value
to get the primitive value.
retrieving firebase data for iOS app using swift
Try this code
let jsonLocations = snapshot.valueInExportFormat() as! NSDictionary
let keys = jsonLocations.allKeys
for key in keys {
let json = jsonLocations[key] as! [String: AnyObject]
self.sections.append(Location(JSONObject: json))
}
Get data out of array of Firebase snapshots
I am not sure if the question can be answered without knowing how the array is built. One gotcha is the For-in loops variable is a NSFastEnumerationIterator so it needs to be downcast to what kind of 'thing' you want it to be. You may have done that so this is just for future reference.
That being said, I crafted up some code and broke it down a bit - maybe it will point you in the right direction.
The code below reads in all nodes by .value and then iterates over the snapshot and stores each child in an array as a FDataSnapshot. Then the code iterates over that array and prints the 'guardian' from each snapshot stored in the array.
I also included your code to print the guardianID and it works as well so my guess is the problem lies with how the array is being initially populated or in this line
for snapshot in self.guardians
as the snapshot is a NSFastEnumerationIterator
let ref = self.myRootRef.child(byAppendingPath: "guardian_node")!
ref.observe(.value, with: { snapshot in
if ( snapshot!.value is NSNull ) {
print("not found")
} else {
var guardianArray = [FDataSnapshot]()
for child in snapshot!.children {
let snap = child as! FDataSnapshot //downcast
guardianArray.append(snap)
}
for child in guardianArray {
let dict = child.value as! NSDictionary
let thisGuardian = dict["guardian"]!
print(thisGuardian)
//your code
let guardianID = (child.value as? NSDictionary)?["guardian"] as? NSString
print(guardianID!)
}
}
})
*This is Swift 3 and Firebase 2.x but the concept is the same.
Related Topics
Does Not Have a Member 'Instantiatewithowner'
Swift 3 - How to Improve Image Quality for Tesseract
Changing Font Size in a Label for Only iPhone 4S, Is This Possible
Get All Urls for Resources in Sub-Directory in Swift
iOS Swift. How to Get a Gps Metadata from Just a Uiimage (Nsurl)
Incorrect Position of Cashapelayer
Swift Tableview Cell Radio Button Implementation
Swipe to Delete on a Tableview That Is Inside a Pageviewcontroller
iOS - Uinavigationcontroller, Hide Navigationbar
Alamofireimage Disk Cache Not Working
Setting a Stateobject Value from Child View Causes Navigationview to Pop All Views
Swift Universal Framework Depending on Pod
Errortype' Is Not Convertible to 'Nserror'
Self.Type Cannot Be Directly Converted to Anyclass in Extension to Objective-C Class in Swift