Android Studio聊天应用Firebase数据无法在RecyclerView检索加载

问题描述
- 已在Firebase Authentication模块存储用户手机号及对应用户Uid,Firebase Storage模块存储用户头像,需要在RecyclerView中实现用户名、对应头像、用户在线/离线状态的展示
- 当前故障:Android聊天应用中RecyclerView无法正常检索加载Firebase数据
- 上方截图为Firebase中存储的认证数据
现有实现代码
Model类
public class firebasemodel { String name; String image; String uid; String status; public firebasemodel() { } public firebasemodel(String name, String image, String uid, String status) { this.name = name; this.image = image; this.uid = uid; this.status = status; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getImage() { return image; } public void setImage(String image) { this.image = image; } public String getUid() { return uid; } public void setUid(String uid) { this.uid = uid; } public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } }
数据检索逻辑
import android.graphics.Color; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.firebase.ui.firestore.FirestoreRecyclerAdapter; import com.firebase.ui.firestore.FirestoreRecyclerOptions; import com.google.firebase.auth.FirebaseAuth; import com.google.firebase.database.DataSnapshot; import com.google.firebase.database.DatabaseReference; import com.google.firebase.database.ValueEventListener; import com.google.firebase.firestore.FirebaseFirestore; import com.google.firebase.firestore.Query; import com.squareup.picasso.Picasso; import static androidx.recyclerview.widget.RecyclerView.VERTICAL; public class chatFragment extends Fragment { private FirebaseFirestore firebaseFirestore; LinearLayoutManager linearLayoutManager; private FirebaseAuth firebaseAuth; ImageView mimageviewofuser; FirestoreRecyclerAdapter<firebasemodel, NoteViewHolder> chatAdapter; RecyclerView mrecyclerview; @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View v = inflater.inflate(R.layout.chatfragment, container, false); firebaseAuth= FirebaseAuth.getInstance(); firebaseFirestore = FirebaseFirestore.getInstance(); mrecyclerview = v.findViewById(R.id.recyclerview); //fetch all user Query query = firebaseFirestore.collection("Users"); FirestoreRecyclerOptions<firebasemodel> allusername = new FirestoreRecyclerOptions.Builder<firebasemodel>().setQuery(query, firebasemodel.class).build(); chatAdapter = new FirestoreRecyclerAdapter<firebasemodel, NoteViewHolder>(allusername) { @Override protected void onBindViewHolder(@NonNull NoteViewHolder noteViewHolder, int i, @NonNull firebasemodel firebasemodel) { noteViewHolder.particularusername.setText(firebasemodel.getName()); String uri = firebasemodel.getImage(); Picasso.get().load(uri).into(mimageviewofuser); if (firebasemodel.getStatus().equals("Online")) { noteViewHolder.statusofuser.setText(firebasemodel.getStatus()); noteViewHolder.statusofuser.setTextColor(Color.GREEN); } else { noteViewHolder.statusofuser.setText(firebasemodel.getStatus()); } noteViewHolder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Toast.makeText(getActivity(), "Item is clicked", Toast.LENGTH_SHORT).show(); } }); } @NonNull @Override public NoteViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.chatviewlayout, parent, false); return new NoteViewHolder(view); } }; mrecyclerview.setHasFixedSize(true); linearLayoutManager = new LinearLayoutManager(getContext()); linearLayoutManager.setOrientation(RecyclerView.VERTICAL); mrecyclerview.setLayoutManager(linearLayoutManager); mrecyclerview.setAdapter(chatAdapter); return v; } public class NoteViewHolder extends RecyclerView.ViewHolder { private TextView particularusername; private TextView statusofuser; public NoteViewHolder(@NonNull View itemView) { super(itemView); particularusername = itemView.findViewById(R.id.nameofuser); statusofuser = itemView.findViewById(R.id.statusofuser); mimageviewofuser = itemView.findViewById(R.id.imageviewofuser); } } @Override public void onStart() { super.onStart(); chatAdapter.startListening(); } @Override public void onStop() { super.onStop(); if(chatAdapter!=null){ chatAdapter.stopListening(); } } }
依赖配置
implementation "androidx.multidex:multidex:2.0.1" implementation 'androidx.appcompat:appcompat:1.4.1' implementation "androidx.recyclerview:recyclerview:1.2.1" implementation 'com.google.android.material:material:1.5.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.3' implementation 'com.google.firebase:firebase-auth:21.0.5' implementation 'com.google.firebase:firebase-database:20.0.4' implementation 'com.google.firebase:firebase-firestore:24.1.0' implementation 'com.google.firebase:firebase-storage:20.0.1' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' implementation 'com.hbb20:ccp:2.5.1' implementation 'com.squareup.picasso:picasso:2.71828' implementation 'com.firebaseui:firebase-ui-firestore:8.0.1' implementation 'com.firebaseui:firebase-ui-database:3.2.2'
故障现象
- 代码无编译、运行报错信息,Firebase认证模块功能运行正常
- 首次安装应用时,聊天页面的RecyclerView布局仅展示一次,随后便消失,无法正常展示聊天应用内的用户列表
修复方案
1. 修复ImageView引用错误
当前代码把列表项的ImageView定义为Fragment全局变量,列表滑动复用时会出现引用错乱,直接导致布局加载异常。
- 删除Fragment全局的
ImageView mimageviewofuser;声明 - 将ImageView移到NoteViewHolder内部作为成员变量,onBindViewHolder加载头像时使用当前ViewHolder持有的ImageView引用
修改后的ViewHolder代码:
public class NoteViewHolder extends RecyclerView.ViewHolder { private TextView particularusername; private TextView statusofuser; private ImageView mimageviewofuser; public NoteViewHolder(@NonNull View itemView) { super(itemView); particularusername = itemView.findViewById(R.id.nameofuser); statusofuser = itemView.findViewById(R.id.statusofuser); mimageviewofuser = itemView.findViewById(R.id.imageviewofuser); } }
onBindViewHolder中加载头像的代码修改为:
String uri = firebasemodel.getImage(); if (uri != null && !uri.isEmpty()) { Picasso.get().load(uri).into(noteViewHolder.mimageviewofuser); }
2. 增加空值判断,修复列表复用异常
当前代码未对Model返回的字段做非空判断,只要有一条用户数据缺失字段就会触发空指针崩溃,导致列表消失;同时离线状态未重置文字颜色,列表复用时会出现状态颜色错乱。
修改后的onBindViewHolder逻辑:
@Override protected void onBindViewHolder(@NonNull NoteViewHolder noteViewHolder, int i, @NonNull firebasemodel firebasemodel) { // 加载用户名 String userName = firebasemodel.getName(); if (userName != null) { noteViewHolder.particularusername.setText(userName); } // 加载头像 String uri = firebasemodel.getImage(); if (uri != null && !uri.isEmpty()) { Picasso.get().load(uri).into(noteViewHolder.mimageviewofuser); } // 加载在线状态 String status = firebasemodel.getStatus(); if (status != null) { noteViewHolder.statusofuser.setText(status); if ("Online".equals(status)) { noteViewHolder.statusofuser.setTextColor(Color.GREEN); } else { noteViewHolder.statusofuser.setTextColor(Color.BLACK); } } // 条目点击事件 noteViewHolder.itemView.setOnClickListener(view -> Toast.makeText(getActivity(), "Item is clicked", Toast.LENGTH_SHORT).show() ); }
3. 统一Firebase UI依赖版本
当前firebase-ui-firestore版本为8.0.1,firebase-ui-database版本为3.2.2,大版本差异会导致内部依赖冲突,数据监听失效。将两个依赖版本统一为8.0.1:
implementation 'com.firebaseui:firebase-ui-firestore:8.0.1' implementation 'com.firebaseui:firebase-ui-database:8.0.1'
4. 确认Firestore数据与权限配置
- Firebase Authentication存储的用户数据不会自动同步到Firestore,需要确认Firestore中存在
Users集合,且集合下每个文档都包含name、image、uid、status四个字段,字段名需和Model类完全一致(大小写敏感) - 确认Firestore安全规则允许已登录用户读取Users集合,避免权限拒绝导致数据拉取失败,可临时使用以下规则验证:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /Users/{userId} { allow read, write: if request.auth != null; } } }
内容的提问来源于stack exchange,提问作者Ayesha Anwer
相关产品推荐
相关产品推荐

