How to Unpack Multiple Levels of Nested JSON in Firebase Database

How to unpack multiple levels of nested JSON in Firebase Database

You'll want to loop over the children of snapshot as shown here:

Database.database().reference().child("app").observe(.childAdded) { (snapshot) in
for child in snapshot.children {
let snap = child as! DataSnapshot //downcast

let dict = snap.value as! [String: Any]
let msg = dict["message"] as! String
}
})

Also see:

  • Get data out of array of Firebase snapshots
  • Swift Firebase -How to get all the k/v when using queryOrdered(byChild: ).queryEqual(toValue: )
  • other questions about looping over child nodes

Updating nested objects firebase

You can use multi-path updates.

var userRef = ref.child(hashedEmail);
var updateObject = {
name: 'Rohan Dalvi',
"externalLinks/website": 'mywebsite'
};
userRef.update(updateObject);

By using the "externalLinks/website" syntax in the object literal it will treat the nested path as an update and not a set for the nested object. This keeps nested data from being deleted.

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.

Get with Flutter a nested JSON from Firebase DataSnapshot

I was also looking on how to handle nested json objects in Flutter with Cloud Firestore and found your post. As I solved my problem, maybe it helps you too: In the "fromJson"-factory of my model I had to parse every element in the list with jsonEncode and jsonDecode before adding it to the model.

in the DatabaseService:

Future<LocationRecordings> getLocationRecordings(String location) async {
DocumentReference document = locationRecordingsCollection.document((location));

DocumentSnapshot documentSnapshot = await document.get();
var data = LocationRecordings.fromJson(documentSnapshot.data);
return data;
}

in the model:

factory LocationRecordings.fromJson(Map<String, dynamic> json) {
List<Recording> recList = [];

List<dynamic>.from(json['recordings']).forEach((content) {
Recording recording = Recording.fromJson(jsonDecode(jsonEncode(content)));
recList.add(recording);
});
return new LocationRecordings(recordings: recList, state: json['state']);
}

Swift Firebase -How to get all the k/v when using queryOrdered(byChild: ).queryEqual(toValue: )

The DataSnapshot class has built-in methods to loop over its children.

reviewsRef?.observeSingleEvent(of: .value, with: { [weak self](snapshot) in
for child in snapshot.children {
let snap = child as! DataSnapshot;
print(snap.key)
print(snap.value)
print(snap.childSnapshot(forPath: "buyerUID").value)
}
})

Also see other search results for looping over Firebase child nodes in Swift.

Query multiple keys on Firebase

I would suggest using a DispatchGroup and mutual exclusion to handle asynchronous functions within a for loop. Here is the code you provided with a DispatchGroup to ensure that all of the asynchronous functions in the loop have completed before it checks the if statement:

let myGroup = DispatchGroup()
var found = false
// iterate through your array
for key in albumKeys {
let album = database.child(self.albumsKey).child(key)
// lock the group
myGroup.enter()
album.observeSingleEventOfType(.Value, withBlock: { snapshot in
if current.name == "My Artwork" {
found = true
}
// after the async work has been completed, unlock the group
myGroup.leave()
})
}
// This block will be called after the final myGroup.leave() of the looped async functions complete
myGroup.notify(queue: .main) {
if !found {
completion(nil)
}
}

Anything contained in the myGroup.notify(queue: .main) { codeblock will not execute until myGroup.enter() and myGroup.leave() have been called the same amount of times. Be sure to call myGroup.leave() within the Firebase observe block (after the async work) and make sure that it is called even if an error is produced from the observe.



Related Topics



Leave a reply



Submit