I started with Firestore and I created a collection MealsDev containing one element. I cannot display it in a recycler view. May you help with it?
In the meantime I have already checked other posts, but I didn't find what I'm doing wrong. The permission on Firebase is set to
allow read, write: if true;
MealsFragment.java:
public class MealsFragment extends Fragment {
private FragmentMealsBinding binding;
String collectionPath= "MealsDev";
DummyRecyclerAdapter dummyRecyclerAdapter;
RecyclerView dummyRecyclerView;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
binding = FragmentMealsBinding.inflate(inflater, container, false);
View root = binding.getRoot();
dummyRecyclerView = root.findViewById(R.id.meals_recycler_view);
FirebaseFirestore db = FirebaseFirestore.getInstance();
Query query = db.collection(collectionPath).limit(10);
FirestoreRecyclerOptions<DummyMeal> options = new FirestoreRecyclerOptions.Builder<DummyMeal>()
.setQuery(query, DummyMeal.class)
.build();
dummyRecyclerAdapter = new DummyRecyclerAdapter(options);
dummyRecyclerView.setAdapter(dummyRecyclerAdapter);
return root;
}
@Override
public void onDestroy() {
super.onDestroy();
binding = null;
}
@Override
public void onStart() {
super.onStart();
dummyRecyclerAdapter.startListening();
}
@Override
public void onStop() {
super.onStop();
dummyRecyclerAdapter.stopListening();
}
}
DummyMeal.java
public class DummyMeal {
String name;
public DummyMeal() {
}
public DummyMeal(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
DummyRecyclerAdapter.java
public class DummyRecyclerAdapter extends FirestoreRecyclerAdapter<DummyMeal, DummyRecyclerAdapter.RecyclerDummyViewHolder> {
public DummyRecyclerAdapter(@NonNull FirestoreRecyclerOptions<DummyMeal> options){
super(options);
}
@Override
protected void onBindViewHolder(@NonNull DummyRecyclerAdapter.RecyclerDummyViewHolder holder, int position, @NonNull DummyMeal model) {
String name = model.getName();
holder.name.setText(name);
}
@NonNull
@Override
public DummyRecyclerAdapter.RecyclerDummyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_view_row_current_meal, parent, false);
return new RecyclerDummyViewHolder(view);
}
public class RecyclerDummyViewHolder extends RecyclerView.ViewHolder {
TextView name;
public RecyclerDummyViewHolder(View view) {
super(view);
name = view.findViewById(R.id.text_view_meal_name);
}
}
}
recycler_view_row_current_meal.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
android:id="@+id/image_view_current_meal"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="80dp"/>
<LinearLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:orientation="vertical"
android:weightSum="3">
<TextView
android:id="@+id/text_view_meal_name"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="2"
android:textSize="18dp"
/>
<TextView
android:id="@+id/text_view_meal_added_date"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/text_view_day_of_week"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/text_view_meal_week"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:textAlignment="viewEnd"
/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
fragment_meals.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"
android:id="@+id/fragment_meals_layout"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="To jest test"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/meals_recycler_view"
android:layout_height="wrap_content"
android:layout_width="match_parent"/>
</FrameLayout>
UPDATE: My aim is to display (in this case) a single record in the recycler view.
The debugger doesn't break if I set breakpoints in onBindViewHolder
and onCreateViewHolder
.
I debugged the service once again setting a breakpoint in MealsFragment after a FirestoreRecyclerOptions in initialized.
It seems that the mSnapshot size is equal to 0. It should be 1 as far as I understand it. Maybe this is the problem? Why?
UPDATE 2: I run the application on a mobile using Android 11 RP1A. In the logs I can see a warning and an error related to GMS. I don't know if this is related. I'm almost sure the data is not displayed due to a problem with a query. Here are the entries from the log:
Failed to register com.google.android.gms.providerinstaller#com.google.android.gms
dswf: 17: 17: API: Phenotype.API is not available on this device. Connection failed with: ConnectionResult{statusCode=DEVELOPER_ERROR, resolution=null, message=null}
and then the error:
Failed to get service from broker.
java.lang.SecurityException: Unknown calling package name 'com.google.android.gms'.
at android.os.Parcel.createExceptionOrNull(Parcel.java:2376)
(...)
You might be missing a LayoutManager
on the RecyclerView
. Without this, the RecyclerView
won't know how to arrange its child views, leading to no data being displayed.
dummyRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
Here’s a full guide from @Alex Mamo post on how to display data from Firestore into a RecyclerView
using Android.
I hope this information helps to resolve your issue.