dub
dub

Reputation: 82

How to access the children of a dynamically added child in Firebase database?

I know how to access "results" because it has a solid name which never changes. But the children under "results" are dynamically added. How am I able to iterate through the children of "results" and then access "datum"?

For each child under "results" I want to make a cardview which will be set in a recyclerviewer with the "datum" in a TextView and the (Base64)Strings in a Imageview.

enter image description here

EDIT I tried this:

resultsRef = FirebaseDatabase.getInstance().getReference("users").child("results"); 

resultsRef.addListenerForSingleValueEvent(new ValueEventListener() {
                    @RequiresApi(api = Build.VERSION_CODES.O)
                    @Override
                    public void onDataChange(@NonNull DataSnapshot snapshot) {

                        for (DataSnapshot ds: snapshot.getChildren()) {
                            String datumStr = ds.child("datum").getValue(String.class);
                            holder.datum.setText(datumStr);
                        }

                    }

                    @Override
                    public void onCancelled(@NonNull DatabaseError error) {

                    }
                });

Upvotes: 1

Views: 241

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 599816

You're creating a reference to getReference("users").child("results"); in the database. But there is no /users/results, so the snapshot you get will be empty.

So you'll need to laod the entire users node, and then get results from each child:

resultsRef = FirebaseDatabase.getInstance().getReference("users").child("results"); 

resultsRef.addListenerForSingleValueEvent(new ValueEventListener() {
    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    public void onDataChange(@NonNull DataSnapshot snapshot) {
        for (DataSnapshot userSnapshot: snapshot.getChildren()) {
            DataSnapshot resultsSnapshot: userSnapshot.getChild("results");
            for (DataSnapshot resultSnapshot: resultsSnapshot.getChildren()) {
                String datumStr = ds.child("datum").getValue(String.class);
                holder.datum.setText(datumStr);
            }
        }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError error) {
        throw error.toException(); // don't ignore errors
    }
});

Note how giving the snapshots meaningful names above helps in understand what they actually refer to.


Also: you're nesting different types of data (user profiles, and their results) under a single top-level node, which the Firebase documentation explicitly recommends against in its best practices.

One disadvantage of your current approach is that in order to for example show a list of user names, you'll end up loading all results for all those users too. Even if that is not a security concern for your app, it's most certainly a waste of bandwidth.

Upvotes: 1

Related Questions