Search code examples
javaandroidfirebasefirebase-realtime-databasefinal

How to set a property value of a class using firebase nested query?


I have a firebase data structure like this Firebase JSON Data

Inside Oli reference there is a "kategori" key (-Ky0RUaYOgB6gks2t3oY) which is having same value as a child in Kategori reference (-Ky0RUaYOgB6gks2t3oY). I'm trying to retrieve all data from Oli reference and set its value to an arraylist using item as DataOli class.

mDbRefOli.orderByChild("nama").addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot childDataSnapshot : dataSnapshot.getChildren()) {
                final DataOli item = new DataOli();
                item.setIdOli(childDataSnapshot.getKey());
                item.setNamaOli(childDataSnapshot.child("nama").getValue().toString());
                mDbRefKategori.child(childDataSnapshot.child("kategori").getValue().toString()).child("nama").addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        item.setKategoriOli(dataSnapshot.getValue(String.class));
                    }

                    @Override
                    public void onCancelled(DatabaseError databaseError) {

                    }
                });
                mDbRefMerk.child(childDataSnapshot.child("merk").getValue().toString()).child("nama").addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        item.setMerkOli(dataSnapshot.getValue(String.class));
                    }

                    @Override
                    public void onCancelled(DatabaseError databaseError) {

                    }
                });
                item.setJenisOli(Integer.parseInt(childDataSnapshot.child("jenis").getValue().toString()));
                item.setHargaOli(Integer.parseInt(childDataSnapshot.child("harga").getValue().toString()));
                item.setKapasitasOli(Double.parseDouble(childDataSnapshot.child("kapasitas").getValue().toString()));
                mListOli.add(item);
            }
            mAdapterOli.notifyDataSetChanged();
            mSwlOli.setRefreshing(false);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });

Instead getting that key and displaying it to user, I'm trying to get "Matic" value from a child (-Ky0RUaYOgB6gks2t3oY) in Kategori reference along with this code item.setKategoriOli(dataSnapshot.getValue(String.class)); to set kategori name in item class. At the end I can't get that "Matic" value, instead I was get null value.

Maybe this problem happened, because AS requires me to define final in item class at the beginning and I'm trying to set kategori value inside another inner class. Can you help me to solving this problem?


Solution

  • //declare the Strings before
    
    
    DatabaseReference newtables = FirebaseDatabase.getInstance().getReference().child("Oli");
    newtables.addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                values = dataSnapshot.child("harga").getValue().toString();
    jenis=dataSnapshot.child("jenis").getValue().toString();
    kap=dataSnapshot.child("kapasitas").getValue().toString();
    kat=dataSnapshot.child("kategori").getValue().toString();
    merk=dataSnapshot.child("merk").getValue().toString();
    nama=dataSnapshot.child("nama").getValue().toString();
                DatabaseReference 
    joins=FirebaseDatabase.getInstance().getReference().child("Kategori");
    joins.orderByKey().equalTo(kat).addChildEventListener(new ChildEventListener() {
                        @Override
                        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                            retrieve = dataSnapshot.child("nama").getValue().toString();
    
                        }
    
                        @Override
                        public void onChildChanged(DataSnapshot dataSnapshot, String s) {
    
                        }
    
                        @Override
                        public void onChildRemoved(DataSnapshot dataSnapshot) {
    
                        }
    
                        @Override
                        public void onChildMoved(DataSnapshot dataSnapshot, String s) {
    
                        }
    
                        @Override
                        public void onCancelled(DatabaseError databaseError) {
    
                        }
                    });
    
            }
    
            @Override
            public void onChildChanged(DataSnapshot dataSnapshot, String s) {
    
            }
    
            @Override
            public void onChildRemoved(DataSnapshot dataSnapshot) {
    
            }
    
            @Override
            public void onChildMoved(DataSnapshot dataSnapshot, String s) {
    
            }
    
            @Override
            public void onCancelled(DatabaseError databaseError) {
    
            }
        });
    

    You can do this, its like a join first you retrieve data from one node and then you use the id and query on it and get the data in the other node.