You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firestore数据可在Toast显示但RecyclerView不加载,FirebaseUI无效

问题:Firestore数据在RecyclerView不显示但Toast可正常展示

尝试从Firestore读取数据并在RecyclerView中展示,但数据未显示且无报错;不过将数据传入Toast时能正常显示。已尝试使用FirebaseUI,但同样无法解决问题。

依赖配置

dependencies {
    implementation 'com.firebaseui:firebase-ui-auth:8.0.1'
    implementation 'com.firebaseui:firebase-ui-database:8.0.1'

    implementation 'androidx.fragment:fragment-ktx:1.5.5'
    implementation 'androidx.appcompat:appcompat:1.5.1'
    implementation 'com.google.android.material:material:1.7.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    implementation 'com.google.firebase:firebase-storage:20.0.1'
    implementation 'com.google.firebase:firebase-database:20.0.4'
    implementation 'androidx.gridlayout:gridlayout:1.0.0'
    implementation 'com.google.firebase:firebase-firestore-ktx:24.4.4'
    testImplementation 'junit:junit:4.13.2'
    implementation 'com.karumi:dexter:6.2.3'
    implementation 'com.firebaseui:firebase-ui-firestore:8.0.1'

    androidTestImplementation 'androidx.test.ext:junit:1.1.4'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0'
}

主Fragment代码

public class createdplaylist extends Fragment {
    ArrayList<String> str=new ArrayList<>();
    RecyclerView recyclerView;
    palylistadapter  palylistadapter;
    Context context;
    FirestoreRecyclerAdapter adapter;
    FirebaseFirestore firestore;

    @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_createdplaylist, container, false);

context=container.getContext();
   firestore = FirebaseFirestore.getInstance();
Query query=firestore.collection("playlist");
recyclerView =view.findViewById(R.id.recyclerr);


query.addSnapshotListener(new EventListener<QuerySnapshot>() {
      @Override
      public void onEvent(@Nullable QuerySnapshot value, @Nullable 
    FirebaseFirestoreException error) {
          for(DocumentSnapshot ds: value.getDocuments()){
              str.add(ds.getId());
              Toast.makeText(context, ds.getId(), Toast.LENGTH_SHORT).show();
          }
      }
     });
      palylistadapter=new palylistadapter(context,str);
        recyclerView.setLayoutManager(new LinearLayoutManager(context));
      recyclerView.setHasFixedSize(true);
        recyclerView.setAdapter(palylistadapter);
     return view;

    }

Adapter代码

public class palylistadapter extends RecyclerView.Adapter<palylistadapter.viewhold> {

Context context;
ArrayList<String>list;

public palylistadapter( Context c,ArrayList<String>s){
this.list=s;
    this.context=c;
}

@NonNull
@Override
public viewhold onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v= LayoutInflater.from(context).inflate(R.layout.playlistlayout,parent,false);
viewhold viewhold=new viewhold(v);
return viewhold;
}

@Override
public void onBindViewHolder(@NonNull viewhold holder, int position) {
    holder.t.setText(list.get(position));
}

@Override
public int getItemCount() {
    if(list.isEmpty())
   return 0;
    else
        return list.size();
}
public class viewhold extends RecyclerView.ViewHolder {
    TextView t;
    public viewhold(@NonNull View itemView) {
        super(itemView);
      t=itemView.findViewById(R.id.textname);
    }
}

问题原因与解决方案

核心原因

Firestore的addSnapshotListener是异步操作,当你初始化palylistadapter并绑定到RecyclerView时,Firestore的数据还未返回,此时str列表为空。后续数据返回并添加到列表后,没有通知Adapter数据已更新,导致RecyclerView不会刷新界面。

解决方案1:手动通知Adapter更新数据

修改Fragment中的快照监听回调,在数据添加完成后调用Adapter的notifyDataSetChanged()方法,触发界面刷新:

query.addSnapshotListener(new EventListener<QuerySnapshot>() {
    @Override
    public void onEvent(@Nullable QuerySnapshot value, @Nullable FirebaseFirestoreException error) {
        if (error != null) {
            // 处理异常,避免崩溃
            return;
        }
        // 清空旧数据,防止重复添加
        str.clear();
        for(DocumentSnapshot ds: value.getDocuments()){
            str.add(ds.getId());
            Toast.makeText(context, ds.getId(), Toast.LENGTH_SHORT).show();
        }
        // 通知Adapter数据已更新
        palylistadapter.notifyDataSetChanged();
    }
});

注意:确保palylistadapter在回调前已完成初始化,避免空指针异常。

解决方案2:使用FirebaseUI的FirestoreRecyclerAdapter(推荐)

利用FirebaseUI封装好的适配器,自动处理数据监听、更新和生命周期管理,无需手动维护列表:

步骤1:创建数据模型类

public class Playlist {
    private String id;

    public Playlist() {}

    public Playlist(String id) {
        this.id = id;
    }

    public String getId() {
        return id;
    }
}

步骤2:修改Fragment代码

public class createdplaylist extends Fragment {
    RecyclerView recyclerView;
    FirebaseFirestore firestore;
    FirestoreRecyclerAdapter<Playlist, PlaylistViewHolder> adapter;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_createdplaylist, container, false);
        Context context = container.getContext();
        firestore = FirebaseFirestore.getInstance();
        recyclerView = view.findViewById(R.id.recyclerr);
        recyclerView.setLayoutManager(new LinearLayoutManager(context));
        recyclerView.setHasFixedSize(true);

        // 构建Firestore查询
        Query query = firestore.collection("playlist");

        // 配置FirestoreRecyclerOptions
        FirestoreRecyclerOptions<Playlist> options = new FirestoreRecyclerOptions.Builder<Playlist>()
                .setQuery(query, snapshot -> new Playlist(snapshot.getId()))
                .build();

        // 初始化适配器
        adapter = new FirestoreRecyclerAdapter<Playlist, PlaylistViewHolder>(options) {
            @NonNull
            @Override
            public PlaylistViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.playlistlayout, parent, false);
                return new PlaylistViewHolder(v);
            }

            @Override
            protected void onBindViewHolder(@NonNull PlaylistViewHolder holder, int position, @NonNull Playlist model) {
                holder.t.setText(model.getId());
                Toast.makeText(context, model.getId(), Toast.LENGTH_SHORT).show();
            }
        };

        recyclerView.setAdapter(adapter);
        return view;
    }

    // 开始监听数据
    @Override
    public void onStart() {
        super.onStart();
        if (adapter != null) {
            adapter.startListening();
        }
    }

    // 停止监听,避免内存泄漏
    @Override
    public void onStop() {
        super.onStop();
        if (adapter != null) {
            adapter.stopListening();
        }
    }

    // 自定义ViewHolder
    public static class PlaylistViewHolder extends RecyclerView.ViewHolder {
        TextView t;
        public PlaylistViewHolder(@NonNull View itemView) {
            super(itemView);
            t = itemView.findViewById(R.id.textname);
        }
    }
}

这种方式会自动处理数据的新增、修改和删除,同时在Fragment生命周期内管理监听的启停,避免不必要的资源消耗。

内容的提问来源于stack exchange,提问作者mm m

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 02:45:16