How to Loop Through and Get All The Keys of The Nested Nodes in Firebase

How do I loop through and get all the keys of the nested nodes in firebase?

In Android

Gives access to all of the immediate children of this snapshot. Can be used in native for loops:

for (DataSnapshot child : parent.getChildren()) { 
//Here you can access the child.getKey()
}

In iOS

Swift 3:

for (child in snapshot.children) { 
//Here you can access child.key
}

Swift 4:

snapshot.children.forEach({ (child) in
<#code#>
})

In Web

snapshot.forEach(function(childSnapshot) {
//Here you can access childSnapshot.key
});

You can put it in a different list or in the same path, the important thing is to keep in mind how much data you are really retrieving when calling an event. And how are you going to query that information... that is why it is recommended in NoSQL to keep flat nodes

Firebase JS: Database call to iterate over nested data

Right now you're reading the root node, and then iterating over its child nodes. That means that child is a snapshot of the key and value of the users node, not of the child nodes under that. You can easily verify that by logging the key of the child node:

firebase.database().ref('/').on('value', (snapshot) => {
snapshot.forEach((child) => {
console.log(child.key);
});
})

This will log:

users

And since the users node does not have a books property, the child.child('books').val() is null.


There are two possible solutions:

  1. Read only the data under the users node, which you do with:

    firebase.database().ref('/users').on('value', (snapshot) => {
    snapshot.forEach((user) => {
    console.log(user.child('books').val());
    });
    })
  2. Handle the users node in your callback, with something like:

    firebase.database().ref('/').on('value', (snapshot) => {
    snapshot.child('users').forEach((user) => {
    console.log(user.child('books').val());
    });
    })

In either case you'll likely also want to iterate over the books, so will need a/another nested loop. Something like:

firebase.database().ref('/users').on('value', (snapshot) => {
snapshot.forEach((user) => {
snapshot.child('books').forEach((book) => {
console.log(book.val());
// or: console.log(book.child('author').val());
});
});
})

Iterating through nested firebase objects - Javascript

You obj is just a normal javascript object, you can just use a simple for loop:

for(var key in obj) {
console.log(obj[key]);
}

or you can use again a forEach on your snapshot:

folderSnapshot.forEach(function (objSnapshot) {
objSnapshot.forEach(function (snapshot) {
var val = snapshot.val();
console.log(val); // Should print your object
});
});

how to iterate through different key values which are generated randomly by firebase

To solve this, there are two approaches. If you are using to add data to the database a model class named Event, to get the data back, please use the following lines of code:

String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference eventsRef = rootRef.child("users").child(uid).child("events");
ValueEventListener valueEventListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
Event event = ds.getValue(Event.class);
Log.d(TAG, event.getName());
}
}

@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
eventsRef.addListenerForSingleValueEvent(valueEventListener);

The second approach would be to use String class, as in the following lines of code:

String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference eventsRef = rootRef.child("users").child(uid).child("events");
ValueEventListener valueEventListener = new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String name = ds.child("name").getValue(String.class);
Log.d(TAG, name);
}
}

@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
eventsRef.addListenerForSingleValueEvent(valueEventListener);

In both cases, the output in the logcat will be:

Yoga Camp
Blood Donation Camp

Fill an array through a nested Firebase data loop Swift

I think what's you're asking is how to iterate over a series of nodes, getting another nodes child keys from that node, then reading the data from the other node based on those keys.

Let me start with a Firebase structure that should help clarify

MainTree
subTree1
some_node
subTree2_0: true
subTree2_1: true
subTree2_2: true
subTree2
subTree2_0:
user_name: "Larry"
subTree2_1:
user_name: "Moe"
subTree2_1:
user_name: "Curly"

That should match up to the structure in the question.

We're going to iterate over the child nodes located in MainTree/subTree1/some_node to get the nodes we want to read from subTree2. I didn't know what some_node was in respect to the rest of the data so I just called it... some_node.

This first section of code reads the subTree1 node child nodes at once, then iterates over them to get each child key - that child key (e.g. subTree2_0) corresponds to a child node in subTree2

func readMainTree() {
let mainTreeRef = self.ref.child("MainTree")
let subTree1Ref = mainTreeRef.child("subTree1")
let someNodeRef = subTree1Ref.child("some_node")
someNodeRef.observeSingleEvent(of: .value, with: { snapshot in
let childNodes = snapshot.children.allObjects as! [DataSnapshot]
for childSnap in childNodes {
self.readSubTree2At(node: childSnap.key)
}
})
}

Within the for..loop, we get each child key and pass that to the function that reads the child data (user_name) and prints it out.

func readSubTree2At(node: String) {
let mainTreeRef = self.ref.child("MainTree")
let subTree2Ref = mainTreeRef.child("subTree2")
let childRef = subTree2Ref.child(node)
childRef.observeSingleEvent(of: .value, with: { snapshot in
let userName = snapshot.childSnapshot(forPath: "user_name").value as? String ?? "No Name"
print(userName)
})
}

and the output is:

Larry
Mo
Curly

You could throw a dispatchGroup into the mix if you want.. here's a solution using a DispatchGroup

func readMainTreeWithDispatch() {
let mainTreeRef = self.ref.child("MainTree")
let subTree1Ref = mainTreeRef.child("subTree1")
let someNodeRef = subTree1Ref.child("some_node")
someNodeRef.observeSingleEvent(of: .value, with: { snapshot in
let childNodes = snapshot.children.allObjects as! [DataSnapshot]

let myGroup = DispatchGroup()

for childSnap in childNodes {
let mainTreeRef = self.ref.child("MainTree")
let subTree2Ref = mainTreeRef.child("subTree2")
let childRef = subTree2Ref.child(childSnap.key)

myGroup.enter()
childRef.observeSingleEvent(of: .value, with: { snapshot in
let userName = snapshot.childSnapshot(forPath: "user_name").value as? String ?? "No Name"
print(userName)
myGroup.leave()
})
}

myGroup.notify(queue: .main) {
print("Finished reading all user names.")
}
})
}

and the output

Larry
Mo
Curly
Finished reading all user names.

For loop with nested Firebase queries Javascript

You need to use Promise.all(), as follows (untested):

  const array = [];
const userIds = [];
return admin
.database()
.ref('/user')
.once('value')
.then((snap1) => {
const promises = [];
snap1.forEach((childSnapshot1) => {
promises.push(
admin
.database()
.ref('/rating/' + childSnapshot1.key)
.once('value')
);
userIds.push(childSnapshot1.key);
});
return Promise.all(promises);
})
.then((snap2) => {
snap2.forEach((childSnapshot2, idx) => {
const rating = childSnapshot2.val();
array.push([userIds[idx], rating]);
});
return array;
})
.catch((error) => {
//...
});

As explained in the Promise.all() doc, "returned values will be in order of the Promises passed, regardless of completion order". So for the userIds and snap2 arrays, their elements orders are corresponding: you can therefore do array.push([userIds[idx], rating]);

Nested queries in Firebase, how to display recovered data with javascript?

That's because firebase calls are run asynchronously and when your for loop executes it's not finished doing the calls. Look into promises and then chaining off when your .on's finish.

If you change your code to this:

var RefMessage = new Firebase('https://chatfbexample.firebaseio.com/user-messages/332');
var oMessages = [];
var All = new Firebase('https://chatfbexample.firebaseio.com/all-messages');
RefMessage.on("value", function (snapshot) {

snapshot.forEach(function (snap) {
var key = snap.key();
var mensajeR = All.child(key);
mensajeR.on('value', function (snap) {
console.log('done call');
var id = snap.val().id;
oMessages[id] = [];
oMessages[id]['id'] = id;
});

});
console.log('trying loop');

for (i in oMessages) {
console.log(oMessages[i]['id']);
}
});

You'll see the 'trying loop' console log before the 'done call' one(s).

Is it possible to iterate through unique children with different values in Firebase Database?

Remove addListenerForSingleValueEvent from child("XRA") and set addListenerForSingleValueEvent on child("Area 71")

Then run a nested loop.

Note : The time complexity is O(n^2)

FirebaseDatabase.getInstance().getReference()
.child("Drawings").child("Area 71").addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {

for (DataSnapshot parentDS : dataSnapshot.getChildren()) {

for (DataSnapshot ds : parentDS.getChildren()) {
key = ds.getKey();
Current_Version = ds.child("Current Version").getValue().toString();
Previous_Version = ds.child("Previous Version").getValue().toString();
}
}

}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.d("TAG", databaseError.getMessage());
}
});


Related Topics



Leave a reply



Submit