Firebase 如何构造NoSQL消息以通过1次查询获取未读信息?

Firebase 如何构造NoSQL消息以通过1次查询获取未读信息?,firebase,data-structures,nosql,Firebase,Data Structures,Nosql,假设我有如下NoSQL结构: messages chat_id (known) message_id (generated automatically) {author, timestamp, content} 我还有users/分支,在那里我可以看到两个相关用户的最后登录。 我想通过1次查询获得给定用户的未读邮件数 您将如何执行此任务?此问题分为两部分: 计算消息的数量 跟踪用户阅读的内容 计算消息的数量 假设您使用的是Firebase实时数据库或Clou

假设我有如下NoSQL结构:

messages  
  chat_id (known)  
    message_id (generated automatically)  
      {author, timestamp, content}
我还有
users/
分支,在那里我可以看到两个相关用户的最后登录。
我想通过1次查询获得给定用户的未读邮件数


您将如何执行此任务?

此问题分为两部分:

  • 计算消息的数量
  • 跟踪用户阅读的内容
  • 计算消息的数量 假设您使用的是Firebase实时数据库或Cloud Firestore,有两种典型的计数方法:

  • 加载未读邮件并在客户端对其进行计数
  • 在数据库中保留一个消息计数器,并在每次读/写消息时更新该计数器
  • 计算客户端的消息是最容易实现的,因此通常是由经验不足的开发人员开始的。当消息数较低时,这种方法可以正常工作。但随着邮件数量的增长,您将下载越来越多的数据

    此时,您将切换到在数据库中保留一个计数器,并在每次写入/删除操作时更新该计数器。这会复制数据,因此具有关系数据库背景的开发人员通常会遇到这种情况。但这是最常见的方法

    您可以在客户端更新计数器,也可以使用这样的服务器端方法

    跟踪用户已阅读的内容 要知道一个用户有多少未读的消息,您需要知道用户已经读了什么。同样,这里有两种常见的方法:

  • 跟踪用户已阅读的每条消息
  • 跟踪用户最近阅读的邮件的ID
  • 跟踪单个消息听起来最正确,所以我看到这项工作已经做了很多。我还看到开发人员在与之斗争,因为它涉及大量的簿记工作。这当然是可能的,但我建议从一个更简单的方法开始

    聊天应用处理(按时间顺序)的消息序列。如果您知道用户看到的最新消息的ID,则可以假定用户也看到了所有早于此的消息

    假设我跟踪您上次阅读的消息的时间戳,它是
    1535725374298
    。我现在可以查询聊天室,仅检索比该聊天室更新的消息:

    firebase.database()
      .ref("chat")
      .child(chatId)
      .orderByChild("timestamp")
      .startAt(1535725374298)
    

    如果您使用的是Firebase身份验证的用户id,uid,它为跨设备的用户提供一致的uid,那么将消息id设置为
    /users/$uid
    文档就是一种方法

    现在,您所要做的就是使用。
    onSnapshot()
    收听
    /users/$user
    文档。一旦客户端采取措施读取快照中的消息,只需从
    users/$uid
    节点删除该消息id即可

    如何在
    users/$uid
    (userDocument)中存储消息id取决于您-可以是一个数组,也可以是一个嵌套对象,甚至可以将消息id单独存储为type
    reference
    ,只要有识别
    type==reference
    客户端的方法(因此,您可以在实时快照中迭代文档字段以查找未读消息)


    这样做的好处是简化了代码/系统。让Firebase在更新时向您发送更新(新的未读消息)。

    看起来很有希望!您能从Firebase实时数据库的角度解释一下吗?