Firestore 数据无法在 RecyclerView 上显示

Posted

技术标签:

【中文标题】Firestore 数据无法在 RecyclerView 上显示【英文标题】:Firestore data can't display on RecyclerView 【发布时间】:2021-10-22 01:37:01 【问题描述】:

The app quit when I change the line我在尝试开发一个显示 Firestore 数据的 android 应用程序时遇到问题。

.

我能知道为什么它没有在我的 RecyclerView 和 EventPage 上显示数据吗?我已经重新检查了所有内容,但我仍然无法找出 EventPage 上没有显示数据的原因。

EventPage.java

public class EventPage extends AppCompatActivity 
    private static final String TAG = "DashboardFragment";
    private FirestoreRecyclerAdapter<EventModel, EventViewHolder> adapter;

    private RecyclerView recyclerView;


    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_event_page);
        
        //Set recyclerView
        recyclerView = findViewById(R.id.recyclerEventCard);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setAdapter(adapter);


        FirebaseFirestore db = FirebaseFirestore.getInstance();
        CollectionReference cRef = db.collection("event");
        Query query = db.collection("event").orderBy("ASC").limit(10);

        FirestoreRecyclerOptions<EventModel> options = new FirestoreRecyclerOptions.Builder<EventModel>()
                .setQuery(query, EventModel.class)
                .build();

        adapter = new FirestoreRecyclerAdapter<EventModel, EventViewHolder>(options) 
            @Override
            protected void onBindViewHolder(@NonNull EventViewHolder holder, int position, @NonNull EventModel model) 
                holder.textViewEName.setText(model.getEName());
                holder.textViewEDate.setText(model.getEDate());
                holder.textViewEVenue.setText(model.getEVenue());
                holder.textViewEDesc.setText(model.getEDesc());
            

            @NonNull
            @Override
            public EventViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) 
                //Changes on XML file. Try it.
                View v=LayoutInflater.from(parent.getContext()).inflate(R.layout.event_card_list, parent, false);
                return new EventViewHolder(v);
            


        ;

        adapter.startListening();
        recyclerView.setAdapter(adapter);

    



EventModel.java

package com.example.myvolunteer;

public class EventModel 
    private String EName;
    private String EDate;
    private String EVenue;
    private String EDesc;

    //Constructor
    public EventModel()

    public EventModel(String EName, String EDate, String EVenue, String EDesc)
        this.EName = EName;
        this.EDate = EDate;
        this.EVenue = EVenue;
        this.EDesc = EDesc;
    

    public String getEName() 
        return EName;
    

    public void setEName(String EName) 
        this.EName = EName;
    

    public String getEDate() 
        return EDate;
    

    public void setEDate(String EDate) 
        this.EDate = EDate;
    

    public String getEVenue() 
        return EVenue;
    

    public void setEVenue(String EVenue) 
        this.EVenue = EVenue;
    

    public String getEDesc() 
        return EDesc;
    

    public void setEDesc(String EDesc) 
        this.EDesc = EDesc;
    















EventViewHolder.java

package com.example.myvolunteer;

import android.view.View;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import org.jetbrains.annotations.NotNull;

class EventViewHolder extends RecyclerView.ViewHolder


    TextView textViewEName, textViewEVenue, textViewEDate, textViewEDesc;
    public EventViewHolder(@NonNull @NotNull View itemView) 
        super(itemView);

        textViewEName = itemView.findViewById(R.id.textEventName);
        textViewEDate = itemView.findViewById(R.id.textEventDate);
        textViewEVenue = itemView.findViewById(R.id.textEventVenue);
        textViewEDesc = itemView.findViewById(R.id.textEventDesc);
    


activity_event_page.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    tools:context=".EventPage">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerEventCard"
        android:layout_
        android:layout_
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

event_card_list.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:orientation="vertical"
    android:layout_
    >

    <androidx.cardview.widget.CardView
        android:layout_
        android:layout_
        app:cardBackgroundColor="#B7F1FE"
        app:cardCornerRadius="10dp"
        app:cardElevation="10dp">

        <LinearLayout
            android:layout_
            android:layout_
            android:orientation="horizontal">

            <LinearLayout
                android:layout_
                android:layout_
                android:layout_weight="1"
                android:gravity="center"
                android:orientation="vertical">

                <TextView
                    android:id="@+id/textEventName"
                    android:layout_
                    android:layout_
                    android:layout_marginLeft="5dp"
                    android:layout_marginTop="10dp"
                    android:text="Event Name"
                    android:textColor="@color/black"
                    android:textSize="25sp"
                    android:textStyle="bold" />

                <TextView
                    android:id="@+id/textEventDate"
                    android:layout_
                    android:layout_
                    android:layout_marginLeft="10dp"
                    android:layout_marginTop="5dp"
                    android:layout_marginRight="10dp"
                    android:layout_marginBottom="5dp"
                    android:text="Date"
                    android:textColor="@color/black"
                    android:textSize="20sp" />

                <TextView
                    android:id="@+id/textEventVenue"
                    android:layout_
                    android:layout_
                    android:layout_marginLeft="10dp"
                    android:layout_marginTop="5dp"
                    android:layout_marginRight="10dp"
                    android:layout_marginBottom="5dp"
                    android:text="Venue"
                    android:textColor="@color/black"
                    android:textSize="20sp" />

                <TextView
                    android:id="@+id/textEventDesc"
                    android:layout_
                    android:layout_
                    android:layout_marginLeft="10dp"
                    android:layout_marginTop="5dp"
                    android:layout_marginRight="10dp"
                    android:layout_marginBottom="5dp"
                    android:text="Description"
                    android:textColor="@color/black"
                    android:textSize="20sp" />

                <androidx.constraintlayout.widget.ConstraintLayout
                    android:layout_
                    android:layout_
                    android:layout_marginLeft="10dp"
                    android:layout_marginTop="5dp"
                    android:layout_marginRight="10dp"
                    android:layout_marginBottom="5dp">

                    <TextView
                        android:id="@+id/createText"
                        android:layout_
                        android:layout_
                        android:text="Created By: "
                        android:textColor="@color/black"
                        android:textSize="18sp"
                        app:layout_constraintBottom_toBottomOf="parent"
                        app:layout_constraintStart_toStartOf="parent"
                        app:layout_constraintTop_toTopOf="parent" />

                    <TextView
                        android:id="@+id/textEventCreatedBy"
                        android:layout_
                        android:layout_
                        android:layout_marginStart="8dp"
                        android:layout_marginLeft="8dp"
                        android:layout_marginTop="8dp"
                        android:text="Leader Name"
                        android:textColor="@color/black"
                        android:textSize="15sp"
                        app:layout_constraintStart_toEndOf="@+id/createText"
                        app:layout_constraintTop_toTopOf="parent" />

                    <Button
                        android:layout_
                        android:layout_
                        android:backgroundTint="#adcae6"
                        android:text="More Info"
                        app:layout_constraintEnd_toEndOf="parent"
                        app:layout_constraintTop_toTopOf="parent"
                        android:textColor="@color/black">

                    </Button>
                </androidx.constraintlayout.widget.ConstraintLayout>


            </LinearLayout>


        </LinearLayout>

    </androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>

【问题讨论】:

如果您遇到问题,最好在发布问题时创建MCVE。您为此问题发布了近 400(四百)行行代码。人们要解析和尝试在线调试的内容很多。请编辑您的问题并隔离问题,这样可以增加获得帮助的机会。 【参考方案1】:

确保您的模型类字符串变量等于您的 firestore 数据字段,因为从 firestore 检索数据非常重要

    private String eventName;
    private String eventDate;
    private String eventVenue;
    private String eventDescription;

    //Constructor
    public EventModel()

    public EventModel(String eventName, String eventDate, String eventVenue, String eventDescription)
        this.eventName = eventName;
        this.eventDate = eventDate;
        this.eventVenue = eventVenue;
        this.eventDescription = eventDescription;
    

    public String geteventName() 
        return eventName;
    

    public void seteventName(String eventName) 
        this.eventName = eventName;
    

    public String geteventDate() 
        return eventDate;
    

    public void seteventDate(String eventDate) 
        this.eventDate = eventDate;
    

    public String geteventVenue() 
        return eventVenue;
    

    public void seteventVenue(String eventVenue) 
        this.eventVenue = eventVenue;
    

    public String geteventDescription() 
        return eventDescription;
    

    public void seteventDescription(String eventDescription) 
        this.eventDescription = eventDescription;
    

【讨论】:

【参考方案2】:

这看起来不对:

Query query = db.collection("event").orderBy("ASC").limit(10);

您告诉 Firestore 按名为 ASC 的字段进行排序,该字段在您的屏幕截图中不存在,因此不会返回任何文档。

您可能希望按升序排序,您可以这样做:

Query query = db.collection("event").orderBy("eventDate", Direction.ASCENDING).limit(10);

请注意,虽然以上将解决文档显示的问题,但它们仍会以错误的顺序显示。这是因为您的 eventDate 字段对于排序日期没有用处。

Firestore 中的字符串按字典顺序排序,按此顺序,“12/7/2021”排在“13/6/2021”之前。

如果您想解决此问题,您可以将日期存储为 Firestore 的内置 Timestamp 类型,或者使用允许排序的字符串格式,例如 "2021-07-12" (which is *after* "2021-07-13"`。

【讨论】:

当我将行更改为 Query query = db.collection("event").orderBy("eventDate", "asc").limit(10); 时,当我尝试转到 EventPage 时,应用程序会立即退出。 听起来您可能遇到了不同的问题。我建议检查你的 logcat 输出,看看现在出了什么问题。 i.stack.imgur.com/IjvnY.png logcat 输出已包含在此链接中。 我也尝试搜索从 logcat 得到的错误,但没有找到任何可以解决问题的方法。 啊,我检查了docs,订单的正确参数是Direction.DESCENDING。我强烈建议在这种情况下将文档放在手边。

以上是关于Firestore 数据无法在 RecyclerView 上显示的主要内容,如果未能解决你的问题,请参考以下文章

无法在 Firestore 中禁用离线数据

无法在 SwiftUI 按钮视图中从 Cloud Firestore 获取数据

无法将数据添加到 Firestore 集合?

无法检索 Firestore 位置和时间戳对象来验证数据表

即使没有数据更改,Firestore 缓存也无法正常工作

Flutter web无法从firestore获取数据