Java Firestore Android 在查询中使用数组列表来显示来自关注用户的帖子

时间:2021-06-12 11:25:54

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

我正在开发一个显示用户关注的用户帖子的活动。对于帖子,我使用了以下结构:

  root --- posts (collection)
             |
             --- uid (documents)
                  |
                  --- userPosts (collection)
                        |
                        --- postId (documents)
                        |     |
                        |     --- title: "Post Title"
                        |     |
                        |     --- date: 4/06/2021
                        |
                        --- postId (documents)
                              |
                              --- title: "Post Title"
                              |
                              --- date: 08/06/2021
                              |
                              --- description: "this is the description of the post"
                              [...etc]

最近我做了一个可视化用户帖子的活动,就是这样。现在,相反,我想显示用户在主页中关注的用户的帖子。 这是“以下”的结构: 帖子(收藏)

   root--- folowing(documents)
              |
              --- uid(collection)
                    |
                    --- userFollowing(documents)
                          |
                          --- followed user(collection) -- followed user(document)
                          |
                          --- followed user (collection) -- followed user(document)

因此,我尝试在 Arraylist 上以这种方式收集用户遵循的所有用户 uid:

FirebaseFirestore.getInstance().collection("following").document(FirebaseAuth.getInstance().getCurrentUser().getUid()).collection("userFollowing").get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
        @Override
        public void onComplete(@NonNull Task<QuerySnapshot> task) {
            if (task.isSuccessful()) {
                for (QueryDocumentSnapshot document : task.getResult()) {
                    document.getData();
                    Uidrecord.add(cont,String.valueOf(document.getData()));
                    cont++;
                }
                int conta = 0;
                for (String item: Uidrecord){
                    if(item == null)
                        break;
                    uidFollowing.add(conta,getFollowingUid(item));
                    Toast.makeText(MainActivity.this, uidFollowing.get(conta), Toast.LENGTH_SHORT).show();
                    conta++;

                }
            } else {
                Toast.makeText(MainActivity.this, task.getException().toString(), Toast.LENGTH_SHORT).show();
            }
        }
    });

(uid 下面是一个用户的所有id) 这是我设置查询以获取单个用户的帖子数据的方式:

Query query = FirebaseFirestore.getInstance()
                .collection("post/" + uidVisit + "/userPosts")
                .limit(1000);

我知道我必须在其中查找帖子的用户 ID,因此这是一个静态查询,因为我必须获取用户的帖子,仅此而已。现在,获取帖子的 uid 包含在一个数组列表中。所以我想知道如何创建动态查询,然后如何获取每个关注的用户的帖子(使用 RecyclerView)。有可能吗?

编辑:正如您从我的完整代码 https://codeshare.io/MNWYb3 中看到的,我尝试放置一个 for(第 225 行)并动态化查询,但结果是它只显示了一个用户,就是这样(似乎覆盖了每个适配器,实际上显示的帖子是最后一个关注的人,所以最后一个数组列表项)

1 个答案:

答案 0 :(得分:1)

您目前在 Firestore 上的结构会有点困难,我认为您应该首先简化您的结构,我建议您保持这样的结构:

users
|
--- uid : "uid1"
    name: "John Doe"
    ...
    usersFollowed : [uid1, uid2, ..., uidn]
    userPosts (collection)
    |
    --- uid: "uuid1"
        title: "Post Title"
        date: 08/06/2021
        description: "this is the description of the post"
        userId: "uid1"
        ....

这样,您只对单个集合及其子集合进行操作,这稍微降低了复杂性,您将在每个用户文档的 usersFollowed 数组字段中存储每个用户关注的用户列表。

接下来你可以随机迭代 usersFollowed 的列表:

List<String> listOfFollowed = new ArrayList<>();
// userDocument is your current user
listOfFollowed = userDocument.get(usersFollowed);
Collections.shuffle(listOfFollowed);
List<DocumentSnaphot> listOfPosts = new ArrayList<DocumentSnaphot>();
for (String item : listOfFollowed) {
    Query query = FirebaseFirestore.getInstance()
                                   .collection("users")
                                   .document(userDocument.getId())
                                   .collection("userPosts")
                                   .document(item)
                                   .orderBy("date")
                                   .limit(1);
    listOfPosts.add(query.get().getDocument().get(0));
}

此代码将按随机顺序为您提供当前用户关注的每个用户的最新帖子。

这不是动态查询,但它会为您提供随机结果,您可以调整最初希望从每个用户那里获得多少帖子背后的逻辑,或者创建一个触发并在以下时间获得更多帖子的函数用户已经看到了你已经获取的所有内容等等。


编辑

检查您的完整代码后,我得出结论,您面临的问题与 FirestoreRecyclerAdapter 的使用有关,该 FirestoreRecyclerAdapter 需要一个查询作为参数,但是,您的用例要求您执行查询一遍又一遍地循环以获得结果。将相同的查询作为 userFollowed 的选项传递将导致您获得仅获取列表中最后一个 FirestoreRecyclerAdapter 的查询,因为这将是循环中的最后一次迭代,并且将是在应用的执行中向前推进,这不是预期的结果。

因此,我建议您不要使用 #include <type_traits> template<class Feature, class... FeatureList> struct has_feature { static constexpr bool value = (std::is_same_v<Feature, FeatureList> || ...); }; template<class Feature, class... FeatureList> inline constexpr bool has_feature_v = has_feature<Feature, FeatureList...>::value; template<class Feature, class ...FeatureList> static constexpr bool isConfiguredWith() { return has_feature_v<Feature, FeatureList...>; } struct CanWalk { }; struct CanNotWalk { }; template<class... FeatureList> struct Robot { static auto configure() { return Robot<WalkFeature < FeatureList...>> (); } private: template<typename ...Config> using WalkFeature = std::conditional_t<isConfiguredWith<CanWalk, Config...>(), CanWalk, CanNotWalk>; }; int main() { Robot<CanWalk> robot_A = Robot<CanWalk>::configure(); Robot<CanNotWalk> robot_B = Robot<>::configure(); return 0; } ,而是使用 ListAdapter,它需要一个 List 作为参数。您将用作此参数的列表将是一个新列表,其中填充了在您创建的循环中反复执行的查询结果。

话虽如此,我建议您查看该文档,看看这可能意味着您的代码中还有哪些其他更改,因为您将更改正在使用的类的类型,这可能会产生意想不到的后果。 this tutorial 也可能有帮助。