【问题标题】:Firebase - Making a homefeed of posts of people you follow (swift)Firebase - 制作您关注的人的帖子的主页(swift)
【发布时间】:2018-08-30 21:55:05
【问题描述】:

对此最具可扩展性的解决方案是什么?

- posts
    - userID
    - userID
          - randomID
          - randomID
- followers
    - personB userid
          - personA userid
- following 
    - personA userid
          - personB userid

我有一个这样的数据库结构。因此,如果 A 开始关注 B,他将被放在 B 的 ID 下的“关注者”下。同时,B 人将被置于 A 人的 ID 下的“关注”下。

如果一个人在应用程序上发帖,它将发布在“帖子”下,并且有一个带有发帖人的用户 ID 的孩子(在下面,孩子的 ID 是他们拥有的不同帖子的随机 ID)。

我试过了

let queryRef = self.ref.child("posts/\(userID)")

 queryRef?.observe(.childAdded, with: { (snapshot) in

    // new post from a friend 

})`

我必须对用户关注的每个人都使用此方法,但如果有很多人发布内容,这将非常慢!

你们有解决这个问题的智能可扩展解决方案吗?

【问题讨论】:

  • 有关基于 Firebase 实时数据库构建的类似 twitter 的应用示例,请参见 firefeed.io。虽然这个例子已经很老了,但数据结构在今天仍然同样适用。

标签: swift firebase firebase-realtime-database social-networking


【解决方案1】:

这确实不可扩展。理想情况下,您希望将数据扇出。例如,您将创建额外的节点,我们称之为feed。每次当前登录的用户关注另一个用户时,您都会将该用户的帖子 ID(如果有)添加到当前用户的提要中,如下所示:

-feed 
   -userID
      -postID

现在,在上面给出的示例中,当人 B 关注人 A 时,如果人 A 有现有帖子,则获取这些帖子的 id 并将它们存储在 person B id 下的 feedtimestamp帖子的(如果你有任何并且你想整理提要上的帖子):

let followRef = Database.database().reference().child("followers")
guard currentUserUid = Auth.auth().currentUser?.uid else { return }

followRef.child(currentUserUid).observeSingleEvent(of: .value, with: { snapshot in
    let followersArraySnapshot = snapshot.children.allObjects as! [DataSnapshot]
    followersArraySnapshot.forEach({ (child) in

        // child.key is the userUid of each user they follow (depends on your model)
        let refFeed = Database.database().reference().child("feed")
        refFeed.child(child.key).child("get the post ID").setValue(["timestamp" : timestamp])
     })
})

然后在您的FeedViewController 或您真正需要显示提要的任何地方,您必须观察当前登录用户的提要(应该返回每个帖子的id),然后观察每个帖子id,将它们缓存/存储在 array 中,然后将它们显示给用户。

整个事情应该是这样的:

var posts = [Post]() // post array (based on your post model)

func observeFeedPosts(withUserId id: String, completion: @escaping (Post) -> Void) {
let feedRef = Database.database().reference().child("feed")
let postRef = Database.database().reference().child("posts")

feedRef.child(id).queryOrdered(byChild: "timestamp").observe(.childAdded, with: { snapshot in
    let postId = snapshot.key
     self.postRef.child(postId).observeSingleEvent(of: .value, with: { snapshot in
    if let dictionary = snapshot.value as? [String : Any] {

        // snapshot.value should return your post, just transform it based on your own model 
        let post = Post.transformDataToImagePost(dictionary: dictionary, key: snapshot.key)
        self.posts.append(post)

      }
   })
}

这样您就不需要将userID 存储在posts 下,而是将帖子本身的id 存储。在某些时候,您想观察当前登录用户发布的所有帖子,因此我建议以类似的方式散出数据 - 创建 myPosts 节点(或任何您想要的名称)并存储信息,如所以:

 -myPosts
     -userId
        -postId:true

那么你所要做的就是观察这个myPosts节点,获取当前登录用户的postId,然后观察posts节点来获取实际的post值。而已。它使数据扁平化。这是我的建议。

【讨论】:

  • 哇,非常感谢老兄!多么棒的答案和有趣的概念……甚至没有想过这样做……只有一个问题,我如何获得(“获取帖子ID”)?就像我如何进入帖子节点并检查用户拥有哪些帖子?获取此人关注的用户的所有 postID 的最佳方法是什么?
  • 另外,假设人 B(那个人 A 正在关注)发布了一个新帖子,那么人 A 将如何在他的数据库中的提要中获取这个 postID?
  • 首先,您的帖子模型需要有一个id,当您在帖子节点中观察帖子时,id 通常是从数据库返回的snapshot.key。一旦用户点击发送,您就必须创建它。就像这样,let newPostId = Database.database().reference().child("posts").childByAutoId().keylet newPostReference = Database.database().reference().child("posts").child(newPostId),这就是你得到你的帖子ID的方式。至于后者,我已经从字面上回答了这是上面的答案。请再读一遍。如果您觉得答案有用,请接受以关闭问题。
  • 如果某人发布了大量帖子,添加每个帖子的 id 看起来像是一项昂贵的操作。如果有人甚至有 200 个帖子,200 次点击将被发送到 firebase(我不确定,我猜这就是 firebase 的工作方式,并计算您的账单、读写次数)。每次我发布一些内容时,我都需要将其发送给关注我的每个人的提要?对这些东西使用 Firebase 云功能会更好吗?
猜你喜欢
  • 2017-04-05
  • 1970-01-01
  • 1970-01-01
  • 2019-05-17
  • 1970-01-01
  • 1970-01-01
  • 2017-04-02
  • 1970-01-01
  • 2018-05-05
相关资源
最近更新 更多