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

无法获取Firebase生成的Post密钥以添加并展示子级评论问题

解决Firebase Realtime Database帖子评论的两个核心问题

看起来你已经搞定了帖子详情页的基础展示,现在卡在评论的添加和展示环节,我来帮你一步步梳理解决:


一、获取帖子密钥并添加评论到对应子节点

首先你已经通过Intent拿到了帖子ID(也就是Firebase生成的push密钥):String id = intent.getStringExtra("post_ID");,这个id就是定位帖子的关键标识,接下来用它来关联评论节点:

1. 补全Firebase初始化与评论写入逻辑

先在onCreate里初始化用户实例,避免空指针:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_show_the_post);
    ButterKnife.bind(this);
    dialog = new Dialog(this);
    intent = getIntent();
    // 初始化Firebase用户和数据库引用
    mAuth = FirebaseAuth.getInstance().getCurrentUser();
    dbRef = FirebaseDatabase.getInstance().getReference();
    getDataFromIntent();
}

然后修改ShowCommentDialog里的btnDone点击事件,把评论写入对应帖子的Comments子节点:

btnDone.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        if(mAuth == null){
            Toasty.error(ShowThePost.this, "请先登录再评论", Toast.LENGTH_SHORT).show();
            return;
        }
        final String category = intent.getStringExtra("category");
        String postId = intent.getStringExtra("post_ID"); // 拿到目标帖子的密钥
        String Notes = txtNotes.getText().toString().trim();
        String SuggestedPrice = txtSuggestprice.getText().toString().trim();
        
        // 校验输入完整性
        if(Notes.isEmpty() || SuggestedPrice.isEmpty()){
            Toasty.warning(ShowThePost.this, "请填写完整评论信息", Toast.LENGTH_SHORT).show();
            return;
        }

        String UserID = mAuth.getUid();
        String UserProfilePic = mAuth.getPhotoUrl() != null ? mAuth.getPhotoUrl().toString() : "";
        String UserName = mAuth.getDisplayName() != null ? mAuth.getDisplayName() : "匿名用户";
        // 生成格式化的评论时间
        String commentDate = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault()).format(new Date());

        CommentsList commentsList = new CommentsList();
        commentsList.setUserID(UserID);
        commentsList.setUserProfilePicture(UserProfilePic);
        commentsList.setCommentDescription(Notes);
        commentsList.setCommentSuggestPrice(SuggestedPrice);
        commentsList.setCommentDate(commentDate);

        // 定位到帖子的Comments节点,push生成评论的唯一ID并写入数据
        dbRef.child("Posts").child(category).child(postId).child("Comments")
             .push().setValue(commentsList)
             .addOnSuccessListener(unused -> {
                 dialog.dismiss();
                 Toasty.success(ShowThePost.this, "评论发布成功", Toast.LENGTH_SHORT).show();
             })
             .addOnFailureListener(e -> 
                 Toasty.error(ShowThePost.this, "发布失败:"+e.getMessage(), Toast.LENGTH_SHORT).show()
             );
    }
});

2. 确认适配器传递了正确的帖子密钥

确保你的BooksAdapter在跳转时,确实把帖子的Firebase密钥传给了ShowThePost,比如在onBindViewHolder中:

@Override
public void onBindViewHolder(@NonNull final BooksItemsHolder holder, int position) {
    final BooksLists book = listy.get(position);
    // 其他数据绑定逻辑...
    
    holder.itemView.setOnClickListener(v -> {
        Intent intent = new Intent(mContext, ShowThePost.class);
        intent.putExtra("post_ID", book.getPostId()); // 传递帖子的Firebase密钥
        intent.putExtra("post_Title", book.getPostTitle());
        // 其他需要传递的字段...
        mContext.startActivity(intent);
    });
}

这里的book.getPostId()是你在BooksLists模型类中存储的帖子密钥字段,要保证从Firebase读取帖子时,把每个帖子的key也保存到模型里。


二、在帖子详情页展示评论

接下来实现评论列表的展示,需要添加RecyclerView来加载评论:

1. 修改布局文件activity_show_the_post.xml

在现有布局下方添加评论RecyclerView:

<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/rv_comments"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="16dp"
    app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/>

2. 创建评论适配器与布局

假设你的CommentsList模型类字段已完善,创建CommentsAdapter:

public class CommentsAdapter extends RecyclerView.Adapter<CommentsAdapter.CommentViewHolder> {

    private List<CommentsList> commentList;
    private Context context;

    public CommentsAdapter(List<CommentsList> commentList, Context context) {
        this.commentList = commentList;
        this.context = context;
    }

    @NonNull
    @Override
    public CommentViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_comment, parent, false);
        return new CommentViewHolder(view);
    }

    @Override
    public void onBindViewHolder(@NonNull CommentViewHolder holder, int position) {
        CommentsList comment = commentList.get(position);
        holder.tvUserName.setText(comment.getUserName());
        holder.tvCommentDate.setText(comment.getCommentDate());
        holder.tvCommentDesc.setText(comment.getCommentDescription());
        holder.tvSuggestedPrice.setText(comment.getCommentSuggestPrice());
        
        // 加载用户头像
        if(!comment.getUserProfilePicture().isEmpty()){
            GlideApp.with(context)
                    .load(comment.getUserProfilePicture())
                    .into(holder.civUserProfile);
        }
    }

    @Override
    public int getItemCount() {
        return commentList.size();
    }

    public static class CommentViewHolder extends RecyclerView.ViewHolder {
        CircularImageView civUserProfile;
        TextView tvUserName, tvCommentDate, tvCommentDesc, tvSuggestedPrice;

        public CommentViewHolder(@NonNull View itemView) {
            super(itemView);
            civUserProfile = itemView.findViewById(R.id.civ_comment_profile);
            tvUserName = itemView.findViewById(R.id.tv_comment_username);
            tvCommentDate = itemView.findViewById(R.id.tv_comment_date);
            tvCommentDesc = itemView.findViewById(R.id.tv_comment_desc);
            tvSuggestedPrice = itemView.findViewById(R.id.tv_comment_suggest_price);
        }
    }
}

对应的item_comment.xml布局可以根据需求设计,包含用户头像、用户名、评论时间、内容和建议价格等控件。

3. 在ShowThePost中监听评论节点并加载数据

初始化评论RecyclerView,添加Firebase监听实时更新评论:

// 新增成员变量
private RecyclerView rvComments;
private CommentsAdapter commentsAdapter;
private List<CommentsList> commentList = new ArrayList<>();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_show_the_post);
    ButterKnife.bind(this);
    dialog = new Dialog(this);
    intent = getIntent();
    mAuth = FirebaseAuth.getInstance().getCurrentUser();
    dbRef = FirebaseDatabase.getInstance().getReference();
    // 初始化评论RecyclerView
    rvComments = findViewById(R.id.rv_comments);
    rvComments.setLayoutManager(new LinearLayoutManager(this));
    commentsAdapter = new CommentsAdapter(commentList, this);
    rvComments.setAdapter(commentsAdapter);
    getDataFromIntent();
    loadComments(); // 加载评论列表
}

// 加载并监听评论变化
private void loadComments(){
    String category = intent.getStringExtra("category");
    String postId = intent.getStringExtra("post_ID");
    
    dbRef.child("Posts").child(category).child(postId).child("Comments")
         .addValueEventListener(new ValueEventListener() {
             @Override
             public void onDataChange(@NonNull DataSnapshot snapshot) {
                 commentList.clear();
                 for(DataSnapshot commentSnapshot : snapshot.getChildren()){
                     CommentsList comment = commentSnapshot.getValue(CommentsList.class);
                     commentList.add(comment);
                 }
                 commentsAdapter.notifyDataSetChanged();
                 // 无评论时可添加空状态提示
             }

             @Override
             public void onCancelled(@NonNull DatabaseError error) {
                 Toasty.error(ShowThePost.this, "加载评论失败:"+error.getMessage(), Toast.LENGTH_SHORT).show();
             }
         });
}

这样当有新评论发布时,RecyclerView会自动更新展示最新内容。


额外注意事项

  • 开发阶段可暂时设置Firebase数据库规则为公开读写,上线后要修改为基于用户权限的规则
  • 确保CommentsList模型类有无参构造函数和完整的getter/setter,否则Firebase无法反序列化数据
  • 处理用户未登录的场景,比如点击评论按钮时先判断登录状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:18:46