user14253444
user14253444

Reputation: 75

Cannot get reference to the automatically generated key in Firebase in Android Studio

I am making an android app with Firebase Realtime Database. This is my database:

{
  "Data" : {
    "UyhzVqsz1BVFKoePa2NEmlPFu382" : {
      "Budget_Income" : {
        "bbbb" : {
          "stData1" : "bbbb",
          "stData2" : "bb",
          "stData3" : "bb",
          "stData4" : "1000"
        }
      },
      "Entry_Income" : {
        "bbbb" : {
          "-MYk3lQuK4X6zcIZtHRD" : {
            "stData1" : "bbbb",
            "stData2" : "20 Apr 2021",
            "stData3" : "ddd",
            "stData4" : "500"
          }
        }
      }
    }
  }
}

I am trying to get the data back in RecyclerView in one activity with the following reference:

 myfire = FirebaseDatabase.getInstance();
                myRef = myfire.getReference().child("Data").child(strUID).child("Entry_Income");
                String uid = myRef.child(title).push().getKey(); // title is reference to "bbb"
                myRef.child(uid).addValueEventListener(new ValueEventListener() {

..........................

The data is empty.

I am able to get one child by the following code:-

 myRef = myfire.getReference().child("Data").child(strUID).child("Entry_Income").child(title);
                myRef.child("-MYk3lQuK4X6zcIZtHRD").addValueEventListener(new ValueEventListener() {
.............

But I want all children like "-MYk3lQuK4X6zcIZtHRD" in my RecyclerView.

My Issue I think the reference to push id is wrong. A solution with example needed.

full code*

 myRef = myfire.getReference().child("Data").child(strUID).child("Budget_Income");
        //-------------------------------



//------------------------------------------
        Toast.makeText(MainActivity.this, "Please Wait a While !", Toast.LENGTH_LONG).show();

//-------------------------
        options1 = new FirebaseRecyclerOptions.Builder<category>()
                .setQuery(myRef, category.class)
                .build();
        final FirebaseRecyclerAdapter<category, holder1> adapter = new FirebaseRecyclerAdapter<category, holder1>(options1) {
            @SuppressLint("SetTextI18n")
            @Override
            protected void onBindViewHolder(@NotNull final holder1 holder, final int i, @NotNull final category passage) {
                final String title = getRef(i).getKey();
                category=title;
                assert title != null;
                myRef = myfire.getReference().child("Data").child(strUID).child("Budget_Income");
                myRef.child(title).addValueEventListener(new ValueEventListener() {

                    @Override
                    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                        if (dataSnapshot.getValue() == null) {
                            Toast.makeText(getApplicationContext(), "Data Not Available", Toast.LENGTH_LONG).show();
                        } else {


                            final String stData1 = (Objects.requireNonNull(dataSnapshot.child("stData1").getValue())).toString();
                            final String stData2 = (Objects.requireNonNull(dataSnapshot.child("stData2").getValue())).toString();
                            final String stData3 = (Objects.requireNonNull(dataSnapshot.child("stData3").getValue())).toString();
                            final String stData4 = (Objects.requireNonNull(dataSnapshot.child("stData4").getValue())).toString();


                            category basic = new category(stData1, stData2, stData3, stData4);
                            holder.tvOne.setText(stData1);
                            holder.tvTwo.setText(stData4);



                        }

                    }

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

                });

                myRef = myfire.getReference().child("Data").child(strUID).child("Entry_Income").child(title);
                String uid = myRef.push().getKey();
                assert uid != null;
                myRef.child(uid).addValueEventListener(new ValueEventListener() {

                    @Override
                    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                        if (dataSnapshot.getValue() == null) {
                            Toast.makeText(getApplicationContext(), "Data Not Available", Toast.LENGTH_LONG).show();
                        } else {

                            final String stData1 = (Objects.requireNonNull(dataSnapshot.child("stData1").getValue())).toString();
                            final String stData2 = (Objects.requireNonNull(dataSnapshot.child("stData2").getValue())).toString();
                            final String stData3 = (Objects.requireNonNull(dataSnapshot.child("stData3").getValue())).toString();
                            final String stData4 = (Objects.requireNonNull(dataSnapshot.child("stData4").getValue())).toString();


                            category basic = new category(stData1, stData2, stData3, stData4);
                            holder.tvThree.setText(stData3);
                            holder.tvFour.setText(stData4);

                        }

                    }

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

                });


            }
            @NonNull
            @Override
            public holder1 onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item1, parent, false);
                return new holder1(v);
            }
        };
        userlist.setAdapter(adapter);
        adapter.startListening();




    }




}

Category Class code*


public class category {




    private String stData1;
    private String stData2;
    private String stData3;
    private String stData4;

    public category() {

    }

    public category(String stData1, String stData2, String stData3, String stData4) {
        this.stData1 = stData1;
        this.stData2 = stData2;
        this.stData3 = stData3;
        this.stData4 = stData4;
    }

    public String getStData1() {
        return stData1;
    }

    public void setStData1(String stData1) {
        this.stData1 = stData1;
    }

    public String getStData2() {
        return stData2;
    }

    public void setStData2(String stData2) {
        this.stData2 = stData2;
    }

    public String getStData3() {
        return stData3;
    }

    public void setStData3(String stData3) {
        this.stData3 = stData3;
    }

    public String getStData4() {
        return stData4;
    }

    public void setStData4(String stData4) {
        this.stData4 = stData4;
    }

}

This is the way to get the data:

       
 myRef = myfire.getReference().child("Data").child(strUID).child("Entry_Income").child(title);
                          
                            myRef.addValueEventListener(new ValueEventListener() {
                                @Override
                                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                                   
                                    for (DataSnapshot data : dataSnapshot.getChildren()) {
                                        String value = data.child("stData4").getValue(String.class);
                                       
                                    }
                                    holder.tvThree.setText(value);
                                   



                                  

                                }


                                @Override
                                public void onCancelled(@NonNull DatabaseError databaseError) {
                                    throw databaseError.toException(); // never ignore errors
                                }
                            });


But the problem is that recycler view is showing more items at bottom without values on scroll.

Upvotes: 1

Views: 453

Answers (2)

Alex Mamo
Alex Mamo

Reputation: 138834

According to my last comment, please see below a solution for getting data from the following reference:

rootRef -> Data -> strUID -> Entry_Income

No matter if there is a single child ("bbbb"), or multiple children under the "Entry_Income" node and Log the data of stData1 out in the logcat. You can similarly do the same thing for the other stData2, stData3, stData4 fields. So please try the code below:

String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference entryIncomeRef = rootRef.child("Data").child(uid).child("Entry_Income");
    entryIncomeRef.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
    @Override
    public void onComplete(@NonNull Task<DataSnapshot> task) {
        if (task.isSuccessful()) {
            for (DataSnapshot titleSnapshot : task.getResult().getChildren()) {
                for (DataSnapshot categorySnapshot : titleSnapshot.getChildren()) {
                    category cat = categorySnapshot.getValue(category.class);
                    Log.d(TAG, cat.getStData1());
                }
            }
        } else {
            Log.d(TAG, task.getException().getMessage()); //Don't ignore potential errors!
        }
    }
});

The key for solving this issue is to loop through the "DataSnapshot" object twice, using a call to ".getChildren()" method. However, this solution will only work if you create your own adapter. It won't work with the "FirebaseRecyclerAdapter". If you need to use the Firebase-UI library, then I recommend you duplicate the data by adding all "bbbb" children into a single node. This practice is called "denormalization" and it's a common practice when it comes to Firebase. For a better understanding, I recommend you see this video, Denormalization is normal with the Firebase Database.

That being said, create a new reference to the newly created node, and pass that object to the FirebaseRecyclerOptions.Builder's "setQuery()" method. That's it!

Upvotes: 1

sozsoy
sozsoy

Reputation: 171

I think the data at that point indeed empty. Try setting a value with that "new id" and then add your listener.

myfire = FirebaseDatabase.getInstance();
                myRef = myfire.getReference().child("Data").child(strUID).child("Entry_Income");
                String uid = myRef.child(title).push().getKey(); // title is reference to "bbb"

//note that this line edited: we are setting a value for the "new" key                
myRef.child(uid).setValue(yourData);

myRef.child(uid).addValueEventListener(new ValueEventListener() {

...
}

Upvotes: 0

Related Questions