简体   繁体   English

如果我具有下一个结构,如何从Firebase实时数据库中检索所有数据?

[英]How to retrieve all data from Firebase Realtime Database if I have the next structure?

I have an app where all authenticated users can post articles(title, content, username, date). 我有一个应用程序,所有通过身份验证的用户都可以发布文章(标题,内容,用户名,日期)。 And I have the structure like this: 我有这样的结构:

结构数据库

Where I have node posts and there I have posts from different users. 在我有节点posts ,那里有来自不同用户的帖子。 For example, I have there user ID and that user has different posts which separated by push() method key. 例如,我有用户ID,并且该用户有不同的帖子,这些帖子由push()方法键分开。 So, how to retrieve all data(all posts) from this structure? 那么,如何从该结构检索所有数据(所有帖子)? I have the next code but I get null : 我有下一个代码,但我得到null

mDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        if (dataSnapshot.child("posts").exists()) {
            for (DataSnapshot dataSnapshot1 : dataSnapshot.child("posts").getChildren()) {
                Post post = dataSnapshot1.getValue(Post.class);
                mAdapter.addPost(post);
            }
        }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        showInformationDialog("Something went wrong! [initializing the list]");
    }
});

And my model class: 我的模型课:

public class Post {

    private String title;
    private String content;
    private String author;
    private String date;

    public Post() {
        // default constructor
    }

    public Post(String title, String content, String author, String date) {
        this.title = title;
        this.content = content;
        this.author = author;
        this.date = date;
    }

    public String getTitle() {
        return title;
    }

    public String getContent() {
        return content;
    }

    public String getAuthor() {
        return author;
    }

    public String getDate() {
        return date;
    }
}

Adding a listener on the root node isn't a good practice at all, meaning that you'll be notified for every change thas is happening in your entire database. 在根节点上添加侦听器根本不是一个好习惯,这意味着在整个数据库中发生的每一次更改都会通知您。 It's a waste of bandwith and resources. 这是对带宽和资源的浪费。 To solve this, attach the listener two levers deeper, like in the following lines of code: 要解决此问题,请将侦听器加深两个杠杆,如以下代码行所示:

String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference uidRef = rootRef.child("posts").child(uid);
ValueEventListener valueEventListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for(DataSnapshot ds : dataSnapshot.getChildren()) {
            Post post = ds.getValue(Post.class);
            Log.d(TAG, post.getAuthor());

            //Add the post object to a list and pass it to the adapter
        }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
    }
};
uidRef.addListenerForSingleValueEvent(valueEventListener);

The output in your logcat will be: 您的logcat中的输出将是:

danchik_kilmez

Edit: 编辑:

There was nothing in your question that indicates that you want to get all posts of all users, however to achieve this you need to make a change in your database structure to allow you perform such a query. 您的问题中没有任何内容表示您希望获得所有用户的所有帖子,但是要实现此目的,您需要更改数据库结构以允许您执行这样的查询。 Using your actual database schema, it's not possible. 使用实际的数据库模式是不可能的。 To solve this, you should duplicate the data. 为了解决这个问题,您应该复制数据。 This practice is called denormalization and is a common practice when it comes to Firebase. 这种做法称为denormalization ,是Firebase的常见做法。 For a better understanding, I recommend you see this video, Denormalization is normal with the Firebase Database . 为了更好地理解,我建议您观看此视频, 使用Firebase数据库可以正常进行非规范化

Also, when you are duplicating data, there is one thing that need to keep in mind. 另外,在复制数据时,请记住一件事。 In the same way you are adding data, you need to maintain it. 用与添加数据相同的方式,您需要对其进行维护。 With other words, if you want to update/detele an item, you need to do it in every place that it exists. 换句话说,如果您想更新/删除项目,则需要在它存在的每个位置进行。

This being said, you should create another node named allPosts , which will hold all posts of all users, like in the following schema example: 话虽如此,您应该创建另一个名为allPosts节点,该节点将保存所有用户的所有帖子,如以下架构示例所示:

Firebase-root
   |
   --- allPosts
         |
         --- postId
              |
              --- //post details
              |
              --- uid: "eNAS ... tfz2"

If you add a listener on posts node, you'll be able to get all post of all users. 如果在posts节点上添加侦听器,则可以获取所有用户的所有post。

You Can simply Use FirebaseRecyclerOptions To Retrieve all The data. 您可以简单地使用FirebaseRecyclerOptions检索所有数据。

FirebaseRecyclerOptions<Post> options = new FirebaseRecyclerOptions.Builder<Post>()
                .setQuery(YourRef,Post.class)
                .build();

        FirebaseRecyclerAdapter<Post,YAdapterHolder>adapter = new
                FirebaseRecyclerAdapter<Post,YAdapterHolder>(options) {
                    @Override
                    protected void onBindViewHolder(@NonNull final YAdapterHolder holder, final int position, @NonNull Post model) {
                        String userIds = getRef(position).getKey();
                        assert userIds != null;
                        YourRef.child(userIds).addValueEventListener(new ValueEventListener() {
                            @Override
                            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                                if (dataSnapshot.getChildrenCount()!=0){
                         //example value retrive
                                  Long data = dataSnapshot.child("data").getValue(Long.class);
                                String data1 = dataSnapshot.child("data1").getValue(String.class);

                                }


                            }

                            @Override
                            public void onCancelled(@NonNull DatabaseError databaseError) {

                            }
                        });




                    }

                    @NonNull
                    @Override
                    public YAdapterHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
                        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.pendinglistmodel,viewGroup,false);
                        return new YAdapterHolder(view);
                    }
                };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM