My JSON is:
{
"Ingredient": {
"hgO9joLhmfh4Wjn7xYpyqcYmNOB3": {
"Garlic": {
"Expiry": "2022-11-12",
"Ingredient": 1
},
"Onion": {
"Expiry": "2022-11-12",
"Ingredient": 1
}
}
}
}
where hgO9joLhmfh4Wjn7xYpyqcYmNOB3
is the current user UID. The problem here is RecycleView shows only a single item from the database which in my case is Onion
node. Why didn't it loop for each children under the fridgeRef.child(currentUserID)
node?
java code
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
ingredientView = inflater.inflate(R.layout.fragment_fridge, container, false);
myIngredientList = (RecyclerView) ingredientView.findViewById(R.id.ingredientList);
myIngredientList.setLayoutManager(new LinearLayoutManager(getContext()));
mAuth = FirebaseAuth.getInstance();
currentUserID = mAuth.getCurrentUser().getUid();
fridgeRef = FirebaseDatabase.getInstance().getReference().child("Ingredient");
return ingredientView;
}
@Override
public void onStart() {
super.onStart();
FirebaseRecyclerOptions<fridgeItem> options
new FirebaseRecyclerOptions.Builder<fridgeItem>()
.setQuery(fridgeRef , fridgeItem.class)
.build();
FirebaseRecyclerAdapter<fridgeItem, fridgeViewHolder> adapter
= new FirebaseRecyclerAdapter<fridgeItem, fridgeViewHolder>(options) {
@Override
protected void onBindViewHolder(@NonNull fridgeViewHolder holder, int position, @NonNull fridgeItem model) {
fridgeRef.child(currentUserID).addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
for(DataSnapshot dataSnapshot : snapshot.getChildren()){
if(snapshot.child("Garlic").hasChild("Ingredient")){
String itemName = "Garlic";
String itemExpiry = snapshot.child("Garlic").child("Expiry").getValue().toString();
holder.ingredName.setText(itemName);
holder.ingredExpiry.setText(itemExpiry);
}
if(snapshot.child("Onion").hasChild("Ingredient")){
String itemName = "Onion";
String itemExpiry = snapshot.child("Onion").child("Expiry").getValue().toString();
holder.ingredName.setText(itemName);
holder.ingredExpiry.setText(itemExpiry);
}
}
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
}
@NonNull
@Override
public fridgeViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.ingredientrecycle, parent, false);
fridgeViewHolder viewHolder = new fridgeViewHolder(view);
return viewHolder;
}
};
myIngredientList.setAdapter(adapter);
adapter.startListening();
}
public static class fridgeViewHolder extends RecyclerView.ViewHolder{
TextView ingredName, ingredExpiry;
public fridgeViewHolder(@NonNull View itemView) {
super(itemView);
ingredName = itemView.findViewById(R.id.itemName);
ingredExpiry = itemView.findViewById(R.id.itemExpiry);
}
}
ingredientrecycle.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:cardElevation="10dp"
app:cardCornerRadius="12dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="3">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:orientation="vertical"
android:layout_weight="2">
<TextView
android:id="@ id/itemName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/ingred"
android:textSize="18sp"
android:fontFamily="@font/roboto" />
<TextView
android:id="@ id/itemExpiry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/expiry"
android:textSize="16sp"
android:layout_marginBottom="16dp"
android:fontFamily="@font/roboto"/>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="16dp"
android:gravity="end"
android:layout_weight="1">
<ImageView
android:id="@ id/deleteBtn"
android:layout_height="20dp"
android:layout_width="20dp"
android:src="@drawable/delete_icon"
android:layout_marginEnd="32dp"/>
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
fragment_fridge.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".fridge">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/fridge"
android:textSize="22sp"
android:layout_marginStart="32dp"
android:layout_marginEnd="32dp"
android:layout_marginTop="32dp"
android:textStyle="bold"
android:textColor="#FF5D36"
android:fontFamily="@font/roboto"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/fridgetext"
android:textSize="20sp"
android:layout_marginStart="32dp"
android:layout_marginEnd="32dp"
android:fontFamily="@font/roboto"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="32dp"
android:paddingEnd="32dp"
android:paddingTop="32dp">
<androidx.recyclerview.widget.RecyclerView
android:id="@ id/ingredientList"
android:layout_width="match_parent"
android:layout_height="615dp" />
</LinearLayout>
</ScrollView>
</LinearLayout>
</FrameLayout>
CodePudding user response:
The adapters from FirebaseUI are designed to show a single child view for each direct child node at the path where you attach the adapter in the database.
In your case, you attach the adapter to /Ingredient
, so it creates a single view for each child node of /Ingredient
, which is just one child node for hgO9joLhmfh4Wjn7xYpyqcYmNOB3
. In that child node you then read handle both its Garlic
and Onion
properties, but you're setting their values on the same view holder - so you end up only seeing the values from Onion
.
If you want to show all ingredients for /Ingredient/hgO9joLhmfh4Wjn7xYpyqcYmNOB3
, you should attach the adapter to that path and simplify its handling to:
FirebaseRecyclerOptions<fridgeItem> options
new FirebaseRecyclerOptions.Builder<fridgeItem>()
.setQuery(fridgeRef.child("hgO9joLhmfh4Wjn7xYpyqcYmNOB3") , fridgeItem.class)
.build();
FirebaseRecyclerAdapter<fridgeItem, fridgeViewHolder> adapter
= new FirebaseRecyclerAdapter<fridgeItem, fridgeViewHolder>(options) {
@Override
protected void onBindViewHolder(@NonNull fridgeViewHolder holder, int position, @NonNull fridgeItem model) {
// String itemName = "Garlic"; TODO: