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

Posted

技术标签:

【中文标题】Java Firestore Android 在查询中使用数组列表来显示来自关注用户的帖子【英文标题】:Java Firestore Android use an arraylist in a query to show posts from followed users 【发布时间】:2021-08-29 01:40:02 【问题描述】:

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

  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 包含在 arraylist 中。所以我想知道如何创建动态查询,然后如何获取每个关注的用户的帖子(使用 RecyclerView)。有可能吗?

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

【问题讨论】:

【参考方案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,因为这将是循环中的最后一次迭代,并且将在应用程序的执行,这不是预期的结果。

因此,我建议您使用ListAdapter,而不是使用FirestoreRecyclerAdapter,它需要一个列表作为参数。您将用作此参数的列表将是一个新列表,其中填充了在您创建的循环中一遍又一遍地执行的查询结果。

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

【讨论】:

你是对的,但不幸的是我无法改变我的结构。但是,我目前必须根据我关注的用户发布帖子的结构是不可能的吗?也许有一个 for 使查询动态化 不是说不可能,但它会更复杂,我认为你可以改变你的结构,因为它看起来不必要地复杂,但既然你不能改变它,当然,我会尝试来想出一些在这种情况下可行的东西。 尝试使用您的代码...顺便说一句,the result is that it only shows the posts of a user and that's it 是什么意思?你的意思是它只会让你得到posts集合中最后一条记录的结果吗?这可能是一种竞争条件,因为您同时对 Firestore 进行了许多异步调用(这是您的结构不是最佳的原因之一)并用新数据覆盖您的数组。 我的建议是在 for 开始之前将您将使用的最终数组的构建更改为空,并在每次迭代时继续向该数组添加更多数据,而不是从一开始就覆盖它(对不起我无法从您的代码中弄清楚) for the result is that it only shows posts from one user and that's it 我的意思是它不会显示数组中用户的所有帖子,而只会显示数组中最后一个用户的帖子。

以上是关于Java Firestore Android 在查询中使用数组列表来显示来自关注用户的帖子的主要内容,如果未能解决你的问题,请参考以下文章

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

Android java:如何创建 POJO 并将其转换为 Cloud Firestore REST API 可接受的 JSON

Android Firestore 过滤器回收视图

在 java 类中为 firestore 文档指定序列化名称

Android Google Firestore 通知用户应用 Firestore 中有新数据

无法使用 android 模拟器上的 Firestore 模拟器访问云 Firestore 后端