简体   繁体   中英

Data from Firestore is not displayed in RecyclerView

I got a problem where my codes do not show any error but the data won't come out in the RecyclerView. Every time I run it, it displays blank at the RecyclerView section. I have set my database rule to allow read, write: if true; but still didn't work.

Here's Java codes:

public class diary_user extends AppCompatActivity  {

RecyclerView recyclerView;
Adapter adapter;
ImageView add;
DrawerLayout drawerLayout;
NavigationView navigationView;
Toolbar toolbar;
TextView date, note, time;

FirestoreRecyclerAdapter adapters;
FirebaseFirestore fStore;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_diary_user);

    date = findViewById(R.id.date_text);
    time = findViewById(R.id.time_text);
    note = findViewById(R.id.note_textview);
    recyclerView = findViewById(R.id.recycleView1);

    fStore = FirebaseFirestore.getInstance();
    FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
    final String current = user.getUid();

    Query query = fStore.collection("Diary").whereEqualTo("UID",current);
    FirestoreRecyclerOptions<ModelClass> options = new FirestoreRecyclerOptions.Builder<ModelClass>()
            .setQuery(query, ModelClass.class)
            .build();

   adapters = new FirestoreRecyclerAdapter<ModelClass, ModelViewHolder>(options) {
        @NonNull
        @Override
        public ModelViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_diary, parent, 
        false);
            return new ModelViewHolder(view);
        }

        @Override
        protected void onBindViewHolder(@NonNull ModelViewHolder holder, int position, @NonNull 
        ModelClass model) {

            holder.date.setText(model.getDate());
            holder.note.setText(model.getText());
            holder.time.setText(model.getTime());
            holder.divider.setText(model.getDivider());

        }
    };

    recyclerView.setHasFixedSize(true);
    recyclerView.setLayoutManager(new LinearLayoutManager(this));
    recyclerView.setAdapter(adapters);
}


private class ModelViewHolder extends RecyclerView.ViewHolder {

    TextView date, time, note, divider;

    public ModelViewHolder(@NonNull View itemView) {
        super(itemView);

        date = itemView.findViewById(R.id.date_text);
        time = itemView.findViewById(R.id.time_text);
        note = itemView.findViewById(R.id.note_textview);
        divider = itemView.findViewById(R.id.line_textview);
    }

}

@Override
protected void onStop() {
    super.onStop();
    if(adapters != null) {
        adapters.stopListening();
    }
}

@Override
protected void onStart() {
    super.onStart();
    if(adapters != null) {
        adapters.startListening();
    }
}
}

ModelClass codes:

public class ModelClass {
String date,time,text,divider;

ModelClass(String date,String time,String text,String divider){
    this.date = date;
    this.time = time;
    this.text = text;
    this.divider = divider;
}

public String getDate() {
    return date;
}

public String getTime() {
    return time;
}

public String getText() {
    return text;
}

public String getDivider() {
    return divider;
}
}

XML codes:

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="100dp"
    android:background="#ffffff">

    <TextView
        android:id="@+id/date_text"
        android:layout_width="120dp"
        android:layout_height="30dp"
        android:layout_marginLeft="30dp"
        android:layout_marginTop="20dp"
        android:text="16/3/2021"
        android:textColor="#000000"
        android:textSize="20sp" />

    <TextView
        android:id="@+id/time_text"
        android:layout_width="80dp"
        android:layout_height="30dp"
        android:layout_marginLeft="290dp"
        android:layout_marginTop="20dp"
        android:text="1:30PM"
        android:textSize="14sp" />

    <TextView
        android:id="@+id/note_textview"
        android:layout_width="200dp"
        android:layout_height="30dp"
        android:layout_marginLeft="30dp"
        android:layout_marginTop="55dp"
        android:text="Feeling good today"
        android:textSize="16sp" />

    <TextView
        android:id="@+id/line_textview"
        android:layout_width="wrap_content"
        android:layout_height="30dp"
        android:layout_below="@+id/time_text"
        android:layout_marginLeft="30dp"
        android:layout_marginTop="25dp"
        android:text="_____________________________________________"
        android:textColor="#CDC7C7"
        android:textSize="16sp" />
</RelativeLayout>

Here's database structure: 数据库结构

add adapters.startListening(); this line mentioned below

adapters.startListening();
recyclerView.setHasFixedSize(true);

also check firestore rules

allow read, write : if true;

also check data collection field name and your model class variable name or you can your anotaion

@PropertyName("Date")

I have set my database rule to allow read, write: if true; but still didn't work.

If you set:

allow read, write: if true;

In your Security Rules, it means that you allow both, read and write operations, to be performed in your Cloud Firestore database. But this is not the reason why your RecylerView is empty. When you try to map a document from Firestore into an object of your "ModelClass", the name of the fields that exist in your class must match the name of your properties that exist in your database. Unfortunately, in your case, the fields don't match. See, the fields in your class start with lowercase, while in the database start with a capital letter, which is not correct.

To solve this, you have two options, you either change the name of your properties in the database to match the one in the class, or you can use an annotation in front of the getters. For example, if you have a field called "date" and the property in the database is called "Date" (upper-case D), your getter should look like this:

@PropertyName("Date")
public String getDate() {
    return date;
}

In this way, you tell the compiler to look for a property called "Date" and not "date".

Because you are using public getters, don't also forget to set the fields in your class as private. If you want to keep them, for example, public, the getters are not needed. You can set the values directly on the public fields. So a minimum class declaration might look like this:

public class ModelClass {
    public String date, time, text, divider;
}

Please also note, that the public no-argument constructor is also not needed, as it is provided by the compiler.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM