Firestore数据无法在RecyclerView中显示,请求技术协助
Firestore数据无法在RecyclerView中展示的排查与解决
现象总结
- Firestore中
MealsDev集合存在1个文档,权限已设置为allow read, write: if true; FirestoreRecyclerOptions的mSnapshot长度为0,onBindViewHolder、onCreateViewHolder完全未触发- Android 11 RP1A设备日志出现GMS相关错误:
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}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) (...)
核心修复步骤
1. 为RecyclerView添加LayoutManager
RecyclerView必须设置LayoutManager才能计算布局、加载子项,你的代码中缺失了这一步,直接导致列表无法显示。在设置适配器前添加:
dummyRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
2. 验证Firestore字段映射
确保Firestore文档中的字段名是name(与DummyMeal类的属性名完全一致,大小写敏感)。如果字段名不匹配,Firestore无法将文档解析为DummyMeal对象,会导致快照为空。
3. 解决GMS兼容问题
日志中的GMS错误可能是Google Play服务版本不兼容导致的:
- 确保设备上的Google Play服务为最新版本
- 使用Firebase BOM统一管理依赖版本,避免版本冲突:
implementation platform('com.google.firebase:firebase-bom:32.7.0') implementation 'com.google.firebase:firebase-firestore' implementation 'com.firebaseui:firebase-ui-firestore:8.0.2' - 模拟器请使用带Google Play服务的官方镜像,不要用无GMS的自定义ROM
4. 验证基础查询是否有效
添加普通Firestore查询监听,确认是否能正常获取数据:
db.collection(collectionPath).get().addOnCompleteListener(task -> { if (task.isSuccessful()) { Log.d("FirestoreTest", "文档数量:" + task.getResult().size()); for (QueryDocumentSnapshot doc : task.getResult()) { Log.d("FirestoreTest", doc.getId() + " => " + doc.getData()); } } else { Log.e("FirestoreTest", "查询失败", task.getException()); } });
如果该监听无法获取数据,说明是Firestore连接/权限问题;如果能获取,问题出在FirestoreRecyclerAdapter的配置上。
5. 确保生命周期方法调用正常
确认startListening()和stopListening()在正确的生命周期触发(你的代码这部分逻辑正确,但可以添加空指针判断避免异常):
@Override public void onStart() { super.onStart(); if (dummyRecyclerAdapter != null) { dummyRecyclerAdapter.startListening(); } } @Override public void onStop() { super.onStop(); if (dummyRecyclerAdapter != null) { dummyRecyclerAdapter.stopListening(); } }
修改后的完整MealsFragment代码
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); // 添加LayoutManager dummyRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); FirebaseFirestore db = FirebaseFirestore.getInstance(); Query query = db.collection(collectionPath).limit(10); // 验证基础查询 db.collection(collectionPath).get().addOnCompleteListener(task -> { if (task.isSuccessful()) { Log.d("FirestoreTest", "文档数量:" + task.getResult().size()); } else { Log.e("FirestoreTest", "查询失败", task.getException()); } }); 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(); if (dummyRecyclerAdapter != null) { dummyRecyclerAdapter.startListening(); } } @Override public void onStop() { super.onStop(); if (dummyRecyclerAdapter != null) { dummyRecyclerAdapter.stopListening(); } } }
内容的提问来源于stack exchange,提问作者Krzychu
相关产品推荐
相关产品推荐

