如何使用随机键从 Firebase 数据库中检索子项到 Android 的回收站视图中?

Posted

技术标签:

【中文标题】如何使用随机键从 Firebase 数据库中检索子项到 Android 的回收站视图中?【英文标题】:How to retrieve child from Firebase Database with a randomkey into recycler view in Android? 【发布时间】:2021-11-03 11:29:42 【问题描述】:

我实际上是 android 编程新手,但我想使用随机键从 Firebase 数据库中检索一个子项(评论)到 RecyclerView。我已经编写了一些代码,但是当我启动应用程序时,孩子(评论)没有显示它也没有给我任何错误。请帮忙,提前谢谢。

我的 Java 代码:

private String commentsID = "";
private ImageView imageView, share, commentimage, profileimage, newslikeimage, send;
private TextView heading, description, newsdate, newstime, newscounter, sharecounter, newcommentcounter, profilename;
private String commentsend, commentcurrentusers, newcommentcurrentusers;
private EditText writecomment;
private DatabaseReference commentRef;
private RecyclerView.LayoutManager layoutManager;
private RecyclerView recyclerView;

private String saveCurrentDate, saveCurrentTime, commentRandomKey;

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_comment);

    commentRef = FirebaseDatabase.getInstance().getReference().child("Comments");
    
    recyclerView = findViewById(R.id.commentrecycler);
    recyclerView.setHasFixedSize(true);
    layoutManager = new LinearLayoutManager(this);
    recyclerView.setLayoutManager(layoutManager);
    recyclerView.setLayoutManager(layoutManager);

    commentsID = getIntent().getStringExtra("comments");

    imageView = findViewById(R.id. newsimage);
    heading = findViewById(R.id. newsname);
    description = findViewById(R.id. newsdescription);
    newsdate = findViewById(R.id. newdate);
    newstime = findViewById(R.id. newtime);
    newscounter = findViewById(R.id. newcounter);
    sharecounter = findViewById(R.id. sharecounter);
    commentimage = findViewById(R.id. commentimage);
    newcommentcounter = findViewById(R.id. newcommentcounter);

    newslikeimage = findViewById(R.id. newslike);
    share = findViewById(R.id. share);
    profileimage = findViewById(R.id. profileimage);
    profilename = findViewById(R.id. profilename);
    send = findViewById(R.id. send);
    writecomment = findViewById(R.id. sendcomment);


@Override
protected void onStart() 
    super.onStart();

    FirebaseUser currentuser = FirebaseAuth.getInstance().getCurrentUser();
    newcommentcurrentusers = currentuser.getUid();

    getCommentsDetails(commentsID);


    send.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v)
        
            commentsend = writecomment.getText().toString();

            if (TextUtils.isEmpty(commentsend))
            
                Toast.makeText(CommentActivity.this, "Please type your comment", Toast.LENGTH_SHORT).show();
            
            else
            
                sendingCommentsToFirebase();
            

        
    );

    FirebaseRecyclerOptions<Comment> options =
            new FirebaseRecyclerOptions.Builder<Comment>()
                    .setQuery(commentRef, Comment.class)
                    .build();

    FirebaseRecyclerAdapter<Comment, CommentsViewHolder> adapter =
            new FirebaseRecyclerAdapter<Comment, CommentsViewHolder>(options) 
                @Override
                protected void onBindViewHolder(@NonNull CommentsViewHolder holder, int position, @NonNull Comment model) 

                    holder.comment.setText(model.getComments());
                

                @NonNull
                @Override
                public CommentsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) 
                    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.comment_item_layout, parent, false);
                    CommentsViewHolder holder = new CommentsViewHolder(view);
                    return holder;
                
            ;
    recyclerView.setAdapter(adapter);
    adapter.startListening();


private void sendingCommentsToFirebase()

    FirebaseUser currentuser = FirebaseAuth.getInstance().getCurrentUser();
    commentcurrentusers = currentuser.getUid();

    Calendar calendar = Calendar.getInstance();

    SimpleDateFormat currentDate = new SimpleDateFormat("MMM dd, yyyy");
    saveCurrentDate = currentDate.format(calendar.getTime());

    SimpleDateFormat currentTime = new SimpleDateFormat("HH:mm:ss a");
    saveCurrentTime = currentTime.format(calendar.getTime());

    commentRandomKey = saveCurrentDate + saveCurrentTime;

    HashMap<String, Object> commentMap = new HashMap<>();
    commentMap.put("comments", commentsend);
    commentMap.put("userID", commentcurrentusers);
    commentMap.put("newspid", commentRandomKey);

    commentRef.child(commentsID).push().setValue(commentMap).addOnCompleteListener(new OnCompleteListener<Void>() 
        @Override
        public void onComplete(@NonNull  Task<Void> task)
        
            if (task.isSuccessful())
            
                Toast.makeText(CommentActivity.this, "Comments added", Toast.LENGTH_SHORT).show();

            
        
    );


private void getCommentsDetails(String commentsID) 
    DatabaseReference newsRef = FirebaseDatabase.getInstance().getReference().child("News");

    newsRef.child(commentsID).addValueEventListener(new ValueEventListener() 
        @Override
        public void onDataChange(@NonNull DataSnapshot snapshot) 
            if (snapshot.exists()) 
                News news = snapshot.getValue(News.class);

                heading.setText(news.getHeading());
                description.setText(news.getDecription());
                profilename.setText(news.getUsername());
                newsdate.setText(news.getDate());
                newstime.setText(news.getTime());
                newscounter.setText(news.getLikes());
                sharecounter.setText(news.getShare());
                newcommentcounter.setText(news.getComment());

                Picasso.get().load(news.getProfileimage()).into(profileimage);
                Picasso.get().load(news.getImage()).into(imageView);
            
        

        @Override
        public void onCancelled(@NonNull DatabaseError error) 

        
    );

这是我的视图持有者

public class CommentActivity extends AppCompatActivity

    private String commentsID = "";
    private ImageView imageView, share, commentimage, profileimage, newslikeimage, send;
    private TextView heading, description, newsdate, newstime, newscounter, sharecounter, newcommentcounter, profilename;
    private String commentsend, commentcurrentusers, newcommentcurrentusers;
    private EditText writecomment;
    private DatabaseReference commentRef;
    private RecyclerView.LayoutManager layoutManager;
    private RecyclerView recyclerView;

    private String saveCurrentDate, saveCurrentTime, commentRandomKey;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_comment);

        commentRef = FirebaseDatabase.getInstance().getReference().child("Comments");
        
        recyclerView = findViewById(R.id.commentrecycler);
        recyclerView.setHasFixedSize(true);
        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setLayoutManager(layoutManager);

        commentsID = getIntent().getStringExtra("comments");

        imageView = findViewById(R.id. newsimage);
        heading = findViewById(R.id. newsname);
        description = findViewById(R.id. newsdescription);
        newsdate = findViewById(R.id. newdate);
        newstime = findViewById(R.id. newtime);
        newscounter = findViewById(R.id. newcounter);
        sharecounter = findViewById(R.id. sharecounter);
        commentimage = findViewById(R.id. commentimage);
        newcommentcounter = findViewById(R.id. newcommentcounter);

        newslikeimage = findViewById(R.id. newslike);
        share = findViewById(R.id. share);
        profileimage = findViewById(R.id. profileimage);
        profilename = findViewById(R.id. profilename);
        send = findViewById(R.id. send);
        writecomment = findViewById(R.id. sendcomment);
    

    @Override
    protected void onStart() 
        super.onStart();

        FirebaseUser currentuser = FirebaseAuth.getInstance().getCurrentUser();
        newcommentcurrentusers = currentuser.getUid();

        getCommentsDetails(commentsID);

        send.setOnClickListener(new View.OnClickListener() 
            @Override
            public void onClick(View v)
            
                commentsend = writecomment.getText().toString();

                if (TextUtils.isEmpty(commentsend))
                
                    Toast.makeText(CommentActivity.this, "Please type your comment", Toast.LENGTH_SHORT).show();
                
                else
                
                    sendingCommentsToFirebase();
                

            
        );

        FirebaseRecyclerOptions<Comment> options =
                new FirebaseRecyclerOptions.Builder<Comment>()
                        .setQuery(commentRef, Comment.class)
                        .build();

        FirebaseRecyclerAdapter<Comment, CommentsViewHolder> adapter =
                new FirebaseRecyclerAdapter<Comment, CommentsViewHolder>(options) 
                    @Override
                    protected void onBindViewHolder(@NonNull CommentsViewHolder holder, int position, @NonNull Comment model) 

                        holder.comment.setText(model.getComments());
                    

                    @NonNull
                    @Override
                    public CommentsViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) 
                        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.comment_item_layout, parent, false);
                        CommentsViewHolder holder = new CommentsViewHolder(view);
                        return holder;
                    
                ;
        recyclerView.setAdapter(adapter);
        adapter.startListening();
    

    private void sendingCommentsToFirebase()
    
        FirebaseUser currentuser = FirebaseAuth.getInstance().getCurrentUser();
        commentcurrentusers = currentuser.getUid();

        Calendar calendar = Calendar.getInstance();

        SimpleDateFormat currentDate = new SimpleDateFormat("MMM dd, yyyy");
        saveCurrentDate = currentDate.format(calendar.getTime());

        SimpleDateFormat currentTime = new SimpleDateFormat("HH:mm:ss a");
        saveCurrentTime = currentTime.format(calendar.getTime());

        commentRandomKey = saveCurrentDate + saveCurrentTime;

        HashMap<String, Object> commentMap = new HashMap<>();
        commentMap.put("comments", commentsend);
        commentMap.put("userID", commentcurrentusers);
        commentMap.put("newspid", commentRandomKey);

        commentRef.child(commentsID).push().setValue(commentMap).addOnCompleteListener(new OnCompleteListener<Void>() 
            @Override
            public void onComplete(@NonNull  Task<Void> task)
            
                if (task.isSuccessful())
                
                    Toast.makeText(CommentActivity.this, "Comments added", Toast.LENGTH_SHORT).show();

                

            
        );

    

    private void getCommentsDetails(String commentsID) 
        DatabaseReference newsRef = FirebaseDatabase.getInstance().getReference().child("News");

        newsRef.child(commentsID).addValueEventListener(new ValueEventListener() 
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) 
                if (snapshot.exists()) 
                    News news = snapshot.getValue(News.class);

                    heading.setText(news.getHeading());
                    description.setText(news.getDecription());
                    profilename.setText(news.getUsername());
                    newsdate.setText(news.getDate());
                    newstime.setText(news.getTime());
                    newscounter.setText(news.getLikes());
                    sharecounter.setText(news.getShare());
                    newcommentcounter.setText(news.getComment());

                    Picasso.get().load(news.getProfileimage()).into(profileimage);
                    Picasso.get().load(news.getImage()).into(imageView);
                
            

            @Override
            public void onCancelled(@NonNull DatabaseError error) 

            
        );
    

这是我的班级:

public class Comment

    private String comments, newspid, userID;

    private Comment()
    

    

    public Comment(String comments, String newspid, String userID) 
        this.comments = comments;
        this.newspid = newspid;
        this.userID = userID;
    

    public String getComments() 
        return comments;
    

    public void setComments(String comments) 
        this.comments = comments;
    

    public String getNewspid() 
        return newspid;
    

    public void setNewspid(String newspid) 
        this.newspid = newspid;
    

    public String getUserID() 
        return userID;
    

    public void setUserID(String userID) 
        this.userID = userID;
    

【问题讨论】:

如果您遇到问题,最好在发布问题时创建MCVE。您为此问题发布了近 400(四百)行行代码。人们需要解析和尝试在线调试的内容很多。请编辑您的问题并隔离问题,这样可以增加获得帮助的机会。 好的,谢谢您的建议 请修剪您的代码,以便更容易找到您的问题。请按照以下指南创建minimal reproducible example。 【参考方案1】:

由于以下参考,您很可能在 RecyclerView 中没有得到任何东西:

commentRef = FirebaseDatabase.getInstance().getReference().child("Comments");

在您的“评论”节点下,没有“评论”类型的对象,只有字符串键(2021 年 9 月 3 日...)。为了能够读取您感兴趣的对象,您应该在数据库中删除该额外级别,因为我看到您已经将“日期”存储到 newspid 属性中,因此不需要它。所以你的架构应该是这样的:

Firebase-root
  |
  --- Comments
        |
        --- $commentId
               |
               --- comments: "This is my comment"
               |
               --- newspid: "Sept 06..."
               |
               --- userID: "D31D..."

而且您的代码可以保持不变。

【讨论】:

嘿约翰。我可以帮助您了解其他信息吗?如果您认为我的回答对您有所帮助,请考虑通过单击左侧投票箭头下方的复选标记(✔️)来接受它。应将颜色更改为绿色。我真的很感激。谢谢!【参考方案2】:

Alex 在他的回答中提出了问题的要点:FirebaseUI 中的适配器只能显示数据库中节点的平面列表,而您有两个嵌套级别。

您可以按照 Alex 的建议进行操作,并将所有 cmets 存储在一个平面列表中,或者您可以从当前数据结构中显示某一天的 cmets:

commentRef = FirebaseDatabase.getInstance().getReference()
                             .child("Comments").child("Sep 03, 202100:21:52 AM");

【讨论】:

非常感谢您的回答,我会这样做的。

以上是关于如何使用随机键从 Firebase 数据库中检索子项到 Android 的回收站视图中?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不从参考节点获取所有数据的情况下获取 Firebase 数据库中的随机键?

如何使用 HashMap 从 Android 的 Firebase 中的子节点获取数据?

从 Python 中的字典中提取不相等的随机键

从python中的字典中获取随机键:值对

具有随机键名的 Graphql 对象

键绑定中的修饰符(SHIFT +(随机键))