【问题标题】:Populate Androidx RecyclerView with CardView with data of two collections from Firebase Firestore使用来自 Firebase Firestore 的两个集合的数据使用 CardView 填充 Androidx RecyclerView
【发布时间】:2020-03-22 15:32:43
【问题描述】:

我在 Cloud Firestore 中有 2 个不同的集合:

  • 帐户(标识符:userId)
    • 用户名
    • 图片网址
  • 帖子(标识符:id)
    • 用户ID
    • 文字
    • 喜欢

目标:我想将这两个集合放在 Fragment 中,并使用 Androidx RecyclerView 来显示带有用户名和图片 URL 的帖子。

我在 build.gradle 中使用了“androidx.recyclerview:recyclerview:1.1.0”。

我使用以下方法从 Firebase 获取帖子并将它们存储在模型“FirebasePost”中:

/**
     * Get all FirebasePost objects from Firebase Firestore collection
     * @return
     */
    public FirestoreRecyclerOptions<FirebasePost> getPosts() {
        Query mQuery = mFirestore.collection("posts").orderBy("createdAt", Query.Direction.DESCENDING);
        // Get the response elements
        FirestoreRecyclerOptions<FirebasePost> response = new FirestoreRecyclerOptions.Builder<FirebasePost>()
                .setQuery(mQuery, FirebasePost.class)
                .build();
        return response;
    }

我通过以下代码填充 RecyclerView:

/**
     * Prepares the Recycler View for showing the Posts data
     * @param mView Gets the current view
     */
    private void prepareRecyclerView(View mView, FirestoreRecyclerOptions<FirebasePost> response) {
        adapter = new FirestoreRecyclerAdapter<FirebasePost, PostHolder>(response) {
            @Override
            public void onBindViewHolder(@NonNull PostHolder holder, int position, @NonNull FirebasePost model) {
                // Bind the FirebasePost object to the PostHolder
                holder.setPostText_to_UI(model.getText());
                holder.setTimestamp_to_UI(model.getCreatedAt());
                holder.setAuthorDisplayName_to_UI(model.getAuthorUserId());
            }

            @NonNull
            @Override
            public PostHolder onCreateViewHolder(@NonNull ViewGroup group, int i) {
                // Create a new instance of the ViewHolder, in this case we are using a custom
                // layout called R.layout.message for each item
                View view = LayoutInflater.from(group.getContext())
                        .inflate(R.layout.posts_item_cardview, group, false);

                return new PostHolder(view);
            }
        };
        mPostsRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
        mPostsRecyclerView.setItemAnimator(new DefaultItemAnimator());
        mPostsRecyclerView.setAdapter(adapter);
        adapter.notifyDataSetChanged();
    }

如何向 Firebase 执行第二个请求以获取用户信息并将其添加到 RecyclerView 的正确位置? 问题是,我得到 AuthorUserId 而不是用户的 displayName,因为在将模型提供给 RecyclerView 之前,我无法对 Firestore 执行另一个请求。

【问题讨论】:

    标签: java android firebase android-recyclerview google-cloud-firestore


    【解决方案1】:

    我想在带有 AndroidX RecyclerView 的 Fragment 中拥有这两个集合,以显示带有用户名和 pictureURL 的帖子。

    Firestore 中的查询很浅,这意味着您只能从运行查询的集合中获取项目。没有办法在单个查询中从不同的集合中获取文档。在 NoSQL 世界中,没有基于两个表中存在的 id 的 INNER JOIN 的概念。 Firestore 不支持一次性跨不同集合进行查询,除非您使用 Firestore collection group queries,但事实并非如此。单个查询只能使用单个集合中文档的属性。

    我能想到的最简单的解决方案是在每个帖子下存储用户数据(用户名和图片URL)。这种做法称为非规范化,是 Firebase 的常见做法。如果您是 NoSQL 数据库的新手,我建议您观看此视频,Denormalization is normal with the Firebase Database 以获得更好的理解。它适用于 Firebase 实时数据库,但同样的规则适用于 Cloud Firestore。

    有关更多信息,我建议您还阅读以下帖子中的答案:

    编辑:

    当您复制数据时,您需要记住一件事。同样,您正在添加数据,您需要维护它。换句话说,如果你想更新/删除一个项目,你需要在它存在的每个地方都这样做。这就是这项技术的工作原理。

    我想避免遍历所有(可能是数百万个)帖子并删除那里重复的用户数据。

    对于数据库中的大量更新/删除,每次都是一种权衡,但这始终取决于您的确切用例和要求。另一种解决方案可能是查询数据库两次,一次是获取帖子,然后是相应的用户详细信息。这种技术并不像你想象的那么慢。因此,您也应该将其视为一种选择。

    您还应该考虑的另一个解决方案是扩充您的数据以接受反向查找。话虽如此,您可以在每个用户对象下添加子集合中的相应帖子。如果需要查询所有用户的所有帖子,则需要集合组查询。

    【讨论】:

    • 由于 GDPR,我需要将用户放在自己的集合中,以便我可以轻松删除用户特定数据。我想避免遍历所有(可能是数百万个)帖子并删除那里重复的用户数据。是否无法按顺序向 Firestore 执行两个请求,然后将完整的模型提供给 Android Recycler View?
    • 我明白了,在这种情况下,请查看我的更新答案。现在可以了吗?
    • "另一种解决方案可能是查询数据库两次,一次是为了获取帖子,然后是相应的用户详细信息。这种技术并没有你想象的那么慢。所以你应该考虑一下作为一种选择。” -> 是的,这正是我想要实现的目标,也是我目前所做的。但是如何在 Android Recycler View 中实现呢?
    • 问题不在于RecyclerView 在于适配器。您可以查询两次并创建包含用户数据的帖子列表。该列表可以传递给适配器并在RecyclerView 中显示所有这些。在这种情况下,您将无法再使用 Firebase-UI 库。如果要使用该库,则应在每个帖子中存储用户数据,以便在显示帖子时可以将其取出。
    猜你喜欢
    • 1970-01-01
    • 2018-09-08
    • 2021-11-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-17
    • 2021-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多