Iterate Over Snapshot Children in Firebase

Iterate over snapshot children in Firebase

If I read the documentation right, this is what you want:

var ref = Firebase(url: MY_FIREBASE_URL)
ref.observeSingleEvent(of: .value) { snapshot in
print(snapshot.childrenCount) // I got the expected number of items
for rest in snapshot.children.allObjects as! [FIRDataSnapshot] {
print(rest.value)
}
}

A better way might be:

var ref = Firebase(url: MY_FIREBASE_URL)
ref.observeSingleEvent(of: .value) { snapshot in
print(snapshot.childrenCount) // I got the expected number of items
let enumerator = snapshot.children
while let rest = enumerator.nextObject() as? FIRDataSnapshot {
print(rest.value)
}
}

The first method requires the NSEnumerator to return an array of all of the objects which can then be enumerated in the usual way. The second method gets the objects one at a time from the NSEnumerator and is likely more efficient.

In either case, the objects being enumerated are FIRDataSnapshot objects, so you need the casts so that you can access the value property.


Using for-in loop:

Since writing the original answer back in Swift 1.2 days, the language has evolved. It is now possible to use a for in loop which works directly with enumerators along with case let to assign the type:

var ref = Firebase(url: MY_FIREBASE_URL)
ref.observeSingleEvent(of: .value) { snapshot in
print(snapshot.childrenCount) // I got the expected number of items
for case let rest as FIRDataSnapshot in snapshot.children {
print(rest.value)
}
}

Iterate over children within a snapshot and get values within each child in Firebase

I assume you are reading the parent node with observeSingleEvent(of: .value so this function reads the data, maintains order, unwraps each child node safely and prints the time. I cast the value to an String but you could use double or something else. I suggest using a double to store your timestamps.

func readTimes() {
let ref = self.ref.child("00001")
ref.observeSingleEvent(of: .value, with: { snapshot in
let allChildren = snapshot.children.allObjects as! [DataSnapshot]
for snap in allChildren {
if let time = snap.childSnapshot(forPath: "timeDetected").value as? String {
print("timeDetected = \(time)")
}
}
})
}

and the output

timeDetected = 2018-05-28T16:00:13Z
timeDetected = 2018-05-28T16:00:18Z
timeDetected = 2018-05-28T16:00:43Z

How to iterate through children in Firebase - Java

The way you deal with an Iterable in Java is with a simple for loop:

for (DataSnapshot child: dataSnapshot.getChildren()) {
String key = child.getKey();
String value = child.getValue().toString();
// do what you want with key and value
}

how to iterate through some children's of every id in Firebase Database android (java)?

If your Shop_details class matches the JSON structure in the shop_details node of the database, you should read the object from only that snapshot:

Shop_details shop_details = postSnapshot.child("shop_details").getValue(Shop_details.class);

Note that it may be better to store the separate aspects of a shop in separate top-level nodes, all with the same key for each shop. Something like:

shop_details: {
"igd1P...": { owner_name: "...", shop_address: "...", ... },
"yDLoU...": { owner_name: "...", shop_address: "...", ... }
},
shop_services: {
"igd1P...": { ... },
"yDLoU...": { ... }
}

That way you can load just the details of each shop, without also loading all their services. This type of structure also allows you to secure the data better.

I recommend reading up on structuring your data specifically on avoiding nested data and flattening your data structures.

Firebase -How to loop through snapshot.hasChild(...)

I got the answer from here and here

let ref = Database...child("users").child(uidABC)
ref.observeSingleEvent(of: .value, with: { (snapshot) in

if !snapshot.exists() {

// this user doesn't exist
return
}

if !snapshot.hasChild("followers") {

// this user exists but has no followers
return
}

// this user exists and has followers now loop through them
let childSnapshot = snapshot.childSnapshot(forPath: "followers") {

for child in childSnapshot.children {

let snap = child as! DataSnapshot

let uid = snap.key

if let dict = snap.value as? [String: Any] {

let timeStamp = dict["timeStamp"] as? Double ?? 0
// eg. check for a specific timeStamp
}
}
})

How would I iterate over all keys to get specific child value?

    let schoolDatabase = Database.database().reference().child("Timetable")
schoolDatabase
.queryOrdered(byChild: "Approved")
.queryEqual(toValue: "Yes")
.observeSingleEvent(of: .value, with: { (snapshot) in
let children = snapshot.children
.compactMap { $0 as? DataSnapshot }

children.forEach { tuple in
print(tuple.key)

if let tupleDictionary = tuple.value as? [String: Any] {
let name = tupleDictionary["Name"] as? String
print(name ?? "-")
}
}
}
)

Or if you are interested only in names (without key):

    let schoolDatabase = Database.database().reference().child("Timetable")
schoolDatabase
.queryOrdered(byChild: "Approved")
.queryEqual(toValue: "Yes")
.observeSingleEvent(of: .value, with: { (snapshot) in
let children = snapshot.children
.compactMap { $0 as? DataSnapshot }
.compactMap { $0?.value as? [String: Any]}
.compactMap { $0["Name"] as? String }


children.forEach { name in
print(name)
}
}
)

Iterating through DataSnapShot.Children stops the execution of code (Unity, Firebase)

I somehow did a workraround to get it fixed.
Actually the SnapShot.Children (by Firebase Unity SDK) is of IEnumerable. Type.
I searched through internet on iterating IEnumerable collections.
And then replaced my code from this :

else if (task.IsCompleted) {
DataSnapshot snapshot = task.Result;
// Do something with snapshot...
foreach(DataSnapshot s in snapshot.Children){
IDictionary dictUsers = (IDictionary)s.Value;
Debug.Log(dictUsers["displayName"]);
}
// After this foreach loop in snapshot.Children, nothing executes
UIManager.instance.ShowOtherUsers();
}

To this:

else if (task.IsCompleted)
{
DataSnapshot snapshot = task.Result;
// Do something with snapshot...

using (var sequenceEnum = snapshot.Children.GetEnumerator())
{
for(int i = 0 ;i while (sequenceEnum.MoveNext())
{
try{
IDictionary dictUser =(IDictionary)sequenceEnum.Current.Value;

Debug.Log("displayName:"+dictUser["displayName"]);

}
catch(System.Exception e){
Debug.Log(e.Message);
}
Debug.Log("At The End!");
UIManager.instance.ShowOtherUsers(); // Now it executes like a Charm


}

It worked like a Charm... What I understand is that this execution was being done a Threaded "Task".
Although, I don't know exactly how is it working or why it was not working with my previous code. Someone, who can provide better information is welcome :)
Cheers!

Firebase for Android, How can I loop through a child (for each child = x do y)

The easiest way is with a ValueEventListener.

    FirebaseDatabase.getInstance().getReference().child("users")
.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
User user = snapshot.getValue(User.class);
System.out.println(user.email);
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});

The User class can be defined like this:

class User {
private String email;
private String userId;
private String username;
// getters and setters...
}


Related Topics



Leave a reply



Submit