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

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

Realtime database

问题描述
  • 已在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 19:36:44