Firebase - 以有效的方式管理用户喜欢的内容 - Swift

时间:2016-12-30 08:55:53

标签: swift firebase firebase-realtime-database

我有一个应用程序,用户可以在应用程序中喜欢这些东西,这显然是因为用户不应该喜欢两次。为了确保这一点,当用户喜欢某些东西时,我将文章的密钥存储在数据库的列表中。问题是当加载表视图以检查用户是否已经喜欢该文章时,最有效的方法是什么。

但在那之后我需要建议,我看到它的方式我有两种方法可以做到这一点。

  1. 我可以在应用程序启动时加载整个列表,然后在加载表视图时,我可以检查文章键是否在已经喜欢的键列表中。 (这是我倾向于的)唯一的问题是,当用户喜欢说1000件事情,然后每次应用程序启动它将不得不从Firebase下载1000行,这是很多,另一个问题意味着文章可以& #39; t开始加载,直到此查询完成。

  2. 将文章密钥传递给单元格,然后在数据库中查询该密钥是否存在,我担心的原因是因为这意味着每次加载单元格时都会有查询,这很多查询和网络活动。我不确定这是否有问题。

  3. 提前致谢! :)

1 个答案:

答案 0 :(得分:2)

我建议不要在客户端防止重复“喜欢”;它最终会像你描述的那样过于详尽。你可以做两件事:

  1. 您可以通过按如下方式构建数据库来防止重复:

    {
      "likes": {
         "user1Key": {
            "objectLikedKey1": true,
            "objectLikedKey2": true
            ...
         }
       }
    }
    
  2. 这样,数据结构可以防止默认重复。把它想象成一套!

    1. 如果您的数据库结构不同,并且出于某种原因需要这样,您可以使用规则来防止重复。 (我将在这里假设一个随机结构,这样你就可以得到这个想法)

      {
        "rules": {
           ".read": true,
           "userLikes": {
              "$user": {
                 ".write": "!data.exists()"
              }
           }
         }
      }
      
    2. 这意味着如果数据尚不存在,您只能写入数据库。

      <强>更新

      在每个对象的结构中创建一个子节点,每个对象包含“喜欢”所述对象的所有用户的列表

          {
            "objects": {
               "object1Key": {
                  "user1Key": true,
                  "user2Key": true
                  ...
                  "timestamp": "2017-01-01 12:00:00 +0000"
                }
             }
          }
      

      如果要检索用户喜欢的所有对象,则点(1)中的结构将非常有用。如果要检索喜欢某个对象的所有用户,则应使用后一种结构。

      如果你有某种类似Facebook的新闻源表加载帖子或对象,那么第二种方法是最好的,它也可以防止重复喜欢。您可能还希望在表中实现某种分页机制,当用户滚动查看更多内容时,它会加载一个合理的数字(比如5或10个)对象。每次检索对象页面时,遍历喜欢该对象的用户并检查当前登录的用户是否是其中之一,如果是,则适当地设置按钮的颜色。

      如果你有很多活动,它会占用一些记忆,但这是你现在最好的方法。我相信最节省内存的解决方案是在服务器而不是客户端设备上循环访问对象的喜欢进程,因此您可以只检索用户是否喜欢它的布尔值,但Firebase不提供该选项。 / p>

      实施提示:

      - 如果您真的想要使用上面建议的分页机制,可以使用以下方法检查是否需要加载更多项目:

      override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
              let lastElement = yourDataSource.count - 1
              if indexPath.row == lastElement {
                  // load more
              }    
      }
      

      -Pagination需要某种标记来设置应该检索哪些项目,因此您应该存储一个时间戳,其中包含您在结构中添加的每个对象(以及喜欢该对象的用户列表,如上所示) 。这个link有一个关于分页的详细答案。如果您熟悉queryOrderedByChild()queryStartingAtValue()queryLimitedToFirst(),您可以轻松获得这个想法,也许无需通过链接中的答案!