Todo App任务不显示排查:云端有数据本地无,报No adapter attached错误
解决你的Firebase Todo App数据不显示问题
嘿,我仔细看了你的代码和错误日志,发现了几个关键问题,咱们一个个来修复:
1. 最核心的问题:Firestore集合名称不匹配
你在添加任务的setData()方法里用的集合名称是"ToDoList"(没有空格):
db.collection("ToDoList").document(id).set(todo)...
但在加载数据的loadData()方法里,你写成了"ToDo List"(多了个空格):
db.collection("ToDo List").get()...
Firestore的集合名称是大小写和空格敏感的,这就导致你的查询根本找不到云端已有的数据,自然没法在App里显示。把loadData()里的集合名称改成"ToDoList"就能解决数据加载的问题。
2. 解决RecyclerView的"No adapter attached"警告
这个警告是因为Firestore的查询是异步操作,在查询结果返回前,RecyclerView没有绑定任何适配器。你可以在onCreate()里先给RecyclerView绑定一个空适配器,之后再更新数据:
修改MainActivity的onCreate()方法:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listItem = (RecyclerView)findViewById(R.id.listTodo); listItem.setHasFixedSize(true); layoutManager = new LinearLayoutManager(this); listItem.setLayoutManager(layoutManager); // 初始化空适配器,解决警告 adapter = new ListItemAdapter(MainActivity.this, new ArrayList<>()); listItem.setAdapter(adapter); db = FirebaseFirestore.getInstance(); //init firebase dialog = new SpotsDialog(MainActivity.this); title = (MaterialEditText)findViewById(R.id.title); description = (MaterialEditText)findViewById(R.id.description); fab = (FloatingActionButton)findViewById(R.id.fab); fab.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if(!isUpdate){ setData(title.getText().toString(),description.getText().toString()); } else { updateData(title.getText().toString(),description.getText().toString()); isUpdate = !isUpdate; //reset flag } } }); //recycler view loadData(); }
优化loadData()方法:
不要每次加载数据都新建适配器,而是更新现有适配器的数据并通知刷新,这样更高效:
private void loadData() { dialog.show(); todoList.clear(); // 先清空旧数据 db.collection("ToDoList") .get() .addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() { @Override public void onComplete(@NonNull Task<QuerySnapshot> task) { dialog.dismiss(); // 不管成功失败都关闭对话框 if (task.isSuccessful()) { for (DocumentSnapshot doc:task.getResult()) { ToDo todo = new ToDo(doc.getString("id"), doc.getString("title"), doc.getString("description")); toDoList.add(todo); } adapter.notifyDataSetChanged(); // 通知适配器数据更新 } else { Toast.makeText(MainActivity.this, "加载失败:" + task.getException().getMessage(), Toast.LENGTH_SHORT).show(); } } }) .addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { dialog.dismiss(); Toast.makeText(MainActivity.this,"" +e.getMessage(),Toast.LENGTH_SHORT).show(); } }); }
3. 额外的小优化
- 在
updateData()里,你不需要再添加一个SnapshotListener来刷新数据,因为update()成功后调用loadData()就已经能刷新列表了,重复监听有点多余。 - 记得在
deleteItem()方法里也关闭对话框(如果有的话),避免用户操作后对话框一直显示。
按照上面的修改,你的App应该就能正常显示云端的任务数据,同时解决掉RecyclerView的警告啦!
内容的提问来源于stack exchange,提问作者M. Umer
相关产品推荐
相关产品推荐

