如何获取当前登录用户正在关注的用户帖子 [英] How do I fetch posts of users that the current signed in user is following

查看:40
本文介绍了如何获取当前登录用户正在关注的用户帖子的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Cloud Firestore存储我的应用程序数据.我在从用户那里获取当前登录用户所关注的帖子时遇到问题.我已经按这样的数据库结构

I am using Cloud Firestore to store my data for my app. I am having a problem with fetching posts from users that the current signed in user follows. I have structured by database like this

Firestore-root
   |
   --- users (collection)
   |     |
   |     --- uid (documents)
   |          |
   |          --- name: "User Name"
   |          |
   |          --- email: "email@email.com"
   |
   --- following (collection)
   |      |
   |      --- uid (document)
   |           |
   |           --- userFollowing (collection)
   |                 |
   |                 --- uid (documents)
   |                 |
   |                 --- uid (documents)
   |
   --- posts (collection)
         |
         ------- postId (document)
                    |
                    |
                    --- uid: user
                    |
                    --- timestamp: 1570044062.261539
                    |
                    --- status: "status"

当我获取供稿的帖子时.我将查询返回的数据分为多个批次,并按时间戳排序该批次.每个批次有10个帖子,但是这些批次不包含来自当前登录用户的用户帖子.它会读取当前存储在数据库中的所有帖子,而不管谁在关注谁

When I fetch the posts for the feed. I split the data returned by the query into batches and order the batch by the timestamp. Each batch has 10 posts however these batches do not contain posts from users that the current signed in user follows. It reads all the posts that are currently stored on the database regardless of who is following who

postsQuery = db.collection("posts").order(by: "timestamp", descending: true).limit(to: 10)

当用户登录并加载其供稿时,fetchFirstBatch()函数会发送对前10个帖子的请求

When the user signs in and loads their feed a request for the first 10 posts is sent by the fetchFirstBatch() function

private func fetchFirstBatch() {
        self.displaySpinner(onView: self.view)
        print("Fetching first batch")
        postsQuery.getDocuments { (snapshot, error) in
            guard let snapshot = snapshot else {
                print("Error retrieving batch: \(error.debugDescription)")
                return
            }

            guard let lastSnapshot = snapshot.documents.last else {
                return
            }

            for document in snapshot.documents {
                let data = document.data()
                let postType = data["post type"] as? String ?? ""

                if postType == PostType.Status.type {
                    let status = data["status"] as? String ?? ""
                    let timestamp = data["timestamp"] as? Double ?? 0
                    let uid = data["user id"] as? String ?? ""
                    let username = data["username"] as? String ?? ""

                    self.posts.append(Post(status: status, timestamp: timestamp, postType: PostType.Status, userId: uid, username: username))
                }
                self.tableView.insertRows(at: [IndexPath(row: self.posts.count - 1, section: 0)], with: .automatic)
            }

            self.lastSnapshot = lastSnapshot

            DispatchQueue.main.async {
                self.tableView.reloadData()
                self.removeSpinner()
            }
        }
    }

一旦用户滚动到包含所有帖子的表格视图的底部,则通过fetchNextBatch()函数获取下一批帖子

Once a user scrolls to the bottom of the table view that contains all the posts the next batch of posts are fetched by the fetchNextBatch() function

private func fetchNextBatch() {
        print("Fetching next batch")
        fetchingBatch = true

        postsQuery.start(afterDocument: lastSnapshot).getDocuments { (snapshot, error) in
            guard let snapshot = snapshot else {
                print("Error retrieving batch: \(error.debugDescription)")
                return
            }

            guard let lastSnapshot = snapshot.documents.last else {
                print("No more batches to fetch")
                self.fetchingBatch = false
                return
            }

            for document in snapshot.documents {
                let data = document.data()
                let postType = data["post type"] as? String ?? ""

                if postType == PostType.Status.type {
                    let status = data["status"] as? String ?? ""
                    let timestamp = data["timestamp"] as? Double ?? 0
                    let uid = data["user id"] as? String ?? ""
                    let username = data["username"] as? String ?? ""

                    self.posts.append(Post(status: status, timestamp: timestamp, postType: PostType.Status, userId: uid, username: username))
                }
                self.tableView.insertRows(at: [IndexPath(row: self.posts.count - 1, section: 0)], with: .automatic)
            }

            self.lastSnapshot = lastSnapshot

            DispatchQueue.main.async {
                self.tableView.reloadData()
            }

            self.fetchingBatch = false
        }
    }

如何附加当前登录用户正在关注的所有用户帖子,同时对每批获取的数据进行分页?我要复制的提要结构是Instagram提要.

How do I append all the posts of the users that the current signed in user is following whilst also paginating the data that is fetched each batch? The feed structure that I am trying to replicate is an Instagram feed.

推荐答案

最好将您的问题分解成较小的部分,因为您提出的问题是您及其实现的全部功能.

It is better to break your question down into smaller pieces, cause the question you've asked is a whole feature of your and its implementation.

我不明白为什么将以下集合与用户的集合分离,然后将它们放在数据模型的顶层,因为基本上在那儿,您已经创建了另一层来添加用户用户文档.您可以将用户重新定位到下一级用户文档.同样,这还是取决于您是否要存储用户(用户关注的人)的全部数据,还是要用他们自己的uid填充他们的文档.

I don't see why you separate the following collection from users' collection and put them in the top level of the data model, because basically in the there, you've created another layer to add a userFollowing sub-collection to the user document. You can relocate the userFollowing to the next level of user documents. Still, again, it depends on the fact that whether you want to store the whole data of the user (the people whom user follows) or fill their documents with the uid of their own.

但是查看数据模型的当前状态,类似于下面的代码可以为您提供帮助:

But looking at the current state of your data model something similar to the code below can help you on this:

const arrayOfPeopleWhichUserFollows = await db.collection('following').doc(userId).collection('userFollowing').get()
      .then(querySnapshot => {
        return  querySnapshot.docs.map((doc) => {
          return doc.data().uid;
        });
      });


    // you have to measure the size of arrayOfPeopleWhichUserFollows to check whether it exceeds the limitation of 10
    // for using in the "where in" query from firestore
    // then breaks the array into a smaller piece, as small as 10 items per array and the repeat the below part for all the
    // fragmented arrays and append all the results into a single variable

    const firstPosts = await db.collection('posts')
      .where('uid', 'in', fragmentedArrayOfPeopleWhichUserFollows)
      .orderBy('timestamp', 'desc').limit(10);

    const posts = await firstPosts.get()
      .then(querySnapshot => {
        const lastVisible = querySnapshot.docs[querySnapshot.docs.length - 1];
        return querySnapshot.docs.map((post) => {
          return post.data();
        });
        const nextPosts = db.collection('posts')
          .where('uid', 'in', fragmentedArrayOfPeopleWhichUserFollows)
          .orderBy('timestamp', 'desc')
          .startAfter(lastVisible)
          .limit(10)
      });

考虑阅读以下链接:

如何在Firestore中编写查询

如何在从Firebase查询时对数据进行分页

如何在Cloud Firestore中管理索引

这篇关于如何获取当前登录用户正在关注的用户帖子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆