0

I want to create a products menu using RecyclerView with image, name, price and ingredients. For retrieving the image, name and price I used one database reference and another one for ingredients. However, when I am trying to get the variable from one onDataChange and use it in the first one (meaning outside the second onDataChange method) it returns null for ingredients.

final DatabaseReference ref = FirebaseDatabase.getInstance().getReference("MENIU");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        for (DataSnapshot menu: dataSnapshot.getChildren()) {
            String key = menu.getKey();
            String category = (String) dataSnapshot.child(key).child("CATEGORIE").getValue();
            Toast.makeText(getApplicationContext(), category, Toast.LENGTH_SHORT).show();
            if (categ.equals(category)) {
                nameObj = (String) dataSnapshot.child(key).child("NUME_PRODUS").getValue();
                priceObj = String.valueOf(dataSnapshot.child(key).child("PRET_PRODUS").getValue());
                imageObj = dataSnapshot.child(key).child("IMAGINE").getValue(String.class);
                Toast.makeText(getApplicationContext(), nameObj + priceObj + imageObj, Toast.LENGTH_SHORT).show();
                final DatabaseReference ingr = FirebaseDatabase.getInstance().getReference().child("MENIU/" + key + "/INGREDIENTE");
                ingr.addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                        String keys = " ";
                        int i = 0;
                        int nr = 0;
                        for (DataSnapshot ingredients: dataSnapshot.getChildren()) {
                            keys = ingredients.getKey();
                            ingredientObj = (String) dataSnapshot.child(keys).child("DENUMIRE").getValue();
                            nr++;
                            list[i++] = ingredientObj;
                        }
                        String[] ingredients = new String[nr];
                        for (int j = 0; j < nr; j++)
                            ingredients[j] = list[j];
                        menuObject.add(new MenuObject(imageObj, nameObj, ingredients, priceObj, R.drawable.plus, "0", R.drawable.minus, R.drawable.button_buy));
                        menuAdapter = new MenuAdapter(menuObject);
                        noodlesEn.setLayoutManager(layoutManager);
                        noodlesEn.setAdapter(menuAdapter);
                    }

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

                    }
                });

            }
        }
    }

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

    }
});

How can I use the list variable outside the onChange method (to have access not only for nameObj, priceObj, imageObj, but for ingredients too)? I have watched some videos and another stackoverflow posts, but all have the same solution from one guy only and I didn't understand how it should look for me.

EDIT

final DatabaseReference ingr = FirebaseDatabase.getInstance().getReference().child("MENIU/" + key + "/INGREDIENTE");
    ingr.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull final DataSnapshot dataSnapshot) {
            readData(new FirebaseCallback() {
                @Override
                public void onCallback(String image, String name, String price) {
                    String keys=" ";
                    int i = 0; int nr = 0;
                    for(DataSnapshot ingredients: dataSnapshot.getChildren()) {
                        keys = ingredients.getKey();
                        ingredientObj = (String) dataSnapshot.child(keys).child("DENUMIRE").getValue();
                        nr++;
                        list[i++] = ingredientObj;
                        Toast.makeText(getApplicationContext(), ingredientObj+ " ", Toast.LENGTH_SHORT).show();
                    }
                    String[] ingredients = new String[nr];
                    for(int j = 0; j< nr; j++) {
                        ingredients[j] = list[j];
                    }
                    menuObject.add(new MenuObject(image, name, ingredients, price, R.drawable.plus, "0", R.drawable.minus, R.drawable.button_buy));
                    Toast.makeText(getApplicationContext(),image + name + price, Toast.LENGTH_SHORT).show();
                    menuAdapter = new MenuAdapter(menuObject);
                    noodlesEn.setLayoutManager(layoutManager);
                    noodlesEn.setAdapter(menuAdapter);
                }
            });

        }
private void readData(final FirebaseCallback firebaseCallback){
    final String categ = title.getText().toString();
    final DatabaseReference ref = FirebaseDatabase.getInstance().getReference("MENIU");
    ValueEventListener valueEventListener = new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            for(DataSnapshot menu: dataSnapshot.getChildren()) {
                key = menu.getKey();
                String category = (String) dataSnapshot.child(key).child("CATEGORIE").getValue();
                // Toast.makeText(getApplicationContext(), category, Toast.LENGTH_SHORT).show();
                if (categ.equals(category)) {
                    nameObj = (String) dataSnapshot.child(key).child("NUME_PRODUS").getValue();
                    priceObj = String.valueOf(dataSnapshot.child(key).child("PRET_PRODUS").getValue());
                    imageObj = dataSnapshot.child(key).child("IMAGINE").getValue(String.class);
                    firebaseCallback.onCallback(imageObj, nameObj, priceObj);
                }
            }
        }

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

        }
    };
    ref.addListenerForSingleValueEvent(valueEventListener);
}

private interface FirebaseCallback {
    void onCallback(String image, String name, String price);
}
Măria
  • 21
  • 4
  • Wich list do you want to use? You can declare list ArrayList as global variable for this class and use it anywhere you want – Alex Rmcf Jun 16 '20 at 10:03
  • I have already did that. The problem is I cannot insert "ingredients" array in my arraylist because it is null. I do not have access to variable "list[]" from the second onDataChange method. That one I want to use for my menuObject. – Măria Jun 16 '20 at 10:16
  • Since data is loaded from Firebase asynchronously, you can only use that data inside the `onDataChange` that is called for it, or in code that you call from inside that `onDataChange`. You'll likely want to set up your own callback, as shown here: https://stackoverflow.com/questions/50434836/getcontactsfromfirebase-method-return-an-empty-list/50435519#50435519 – Frank van Puffelen Jun 16 '20 at 13:39
  • I did something similar and it still doesn't give me access to the variables from the first reference. Could you show me based on my example the exact code I need, please? I have edited my code. – Măria Jun 16 '20 at 18:01

0 Answers0