在Firebase中构建聊天应用的数据

Nil*_*bol 13 firebase swift firebase-realtime-database

我按照Firebase指南来构建聊天应用的数据.他们建议如下所示的结构.

{
  // Chats contains only meta info about each conversation
  // stored under the chats's unique ID
  "chats": {
    "one": {
      "title": "Historical Tech Pioneers",
      "lastMessage": "ghopper: Relay malfunction found. Cause: moth.",
      "timestamp": 1459361875666
    },
    "two": { ... },
    "three": { ... }
  },

  // Conversation members are easily accessible
  // and stored by chat conversation ID
  "members": {
    // we'll talk about indices like this below
    "one": {
      "ghopper": true,
      "alovelace": true,
      "eclarke": true
    },
    "two": { ... },
    "three": { ... }
  },

  // Messages are separate from data we may want to iterate quickly
  // but still easily paginated and queried, and organized by chat
  // converation ID
  "messages": {
    "one": {
      "m1": {
        "name": "eclarke",
        "message": "The relay seems to be malfunctioning.",
        "timestamp": 1459361875337
      },
      "m2": { ... },
      "m3": { ... }
    },
    "two": { ... },
    "three": { ... }
  }
}
Run Code Online (Sandbox Code Playgroud)

如何构建我的用户数据,以便我可以轻松显示他们所属的所有聊天列表,并为每个聊天显示最后一条消息和时间戳.如果我执行以下结构:

   "users": {
    "ghopper": {
      "name": "Gary Hopper",
      "chats": {
          "one: true",
          "two": true
      }
    },
    "alovelace" { ... }
  },
Run Code Online (Sandbox Code Playgroud)

通过执行(在swift中),我可以轻松地获取特定用户的每个聊天组的列表,例如ghopper:

ref.child("users").child("ghopper").child("chats").observeSingleEventOfType(.Value, withBlock: { (snapshot) in
  //do something with data
}
Run Code Online (Sandbox Code Playgroud)

但是,我不会在此快照中拥有lastMessage和timestamp.访问此数据需要执行哪些操作?

  • 为每个用户复制所有这些数据?即添加用户/ ghopper/chats/one/{"lastMessage":"ghopper:发现继电器故障.原因:飞蛾.","时间戳":1459361875666}
  • 针对用户所属的每个聊天(添加多个列表器)查询"聊天/ specificGroupId"?
  • 还有其他方法吗?

Jay*_*Jay 17

如何构建我的用户数据,以便我可以轻松显示他们所属的所有聊天列表,并为每个聊天显示最后一条消息和时间戳.

通过添加聊天节点中的用户来更改聊天结构

"chats": {
    "one": {
      "title": "Historical Tech Pioneers",
      "lastMessage": "ghopper: Relay malfunction found. Cause: moth.",
      "timestamp": 1459361875666
      users
       uid_1: true
       uid_3: true
    },
    "two": { ... },
Run Code Online (Sandbox Code Playgroud)

然后,您可以深入查询特定用户所参与的所有聊天 - 这将返回uid_3所涉及的聊天

chatsRef.queryOrderedByChild("users/uid_3").queryEqualToValue(true)
     .observeSingleEventOfType(.Value, withBlock: { snapshot in

     //.Value can return multiple nodes within the snapshot so iterate over them
     for child in snapshot.children {
          let lastmsg = child.value["lastMessage"] as! String
          let timestamp = child.value["timestamp"] as! String
          print(lastmsg)
          print(timestamp)
     }     
})
Run Code Online (Sandbox Code Playgroud)

请注意,每个firebase用户都具有通过auth.uid创建用户时获得的谨慎用户ID.这应该(通常)用作每个用户的密钥.


Sha*_*rud 3

在您拥有用户所在的所有聊天列表的块中,您可以执行以下操作:

var dictionary: [String: Long]   
var lastMessage: String 
for chat in listOfChatsUserIsIn
    ref.child("chats").child("\(chat)").child("lastMessage").observeSingleEventOfType(.Value, withBlock: { (snapshot) in
        lastMessage = snapshot
        ref.child("chats").child("\(chat)").child("timestamp").observeSingleEventOfType(.Value, withBlock: { (snapshot) in
            //add timestamp and last message to dictionary
        }
    }
Run Code Online (Sandbox Code Playgroud)

我不知道我的语法有多正确。还在学习firebase。但是,我认为这基本上是你的第二个建议。不知道您还能如何获取数据。这将是 O(2n),不过这​​还不错。

[[更新1]]

我对我的代码很懒。我把 lastMessage = snapshot 保存起来,这样你就可以将它添加到下一个块的字典中。

至于 Firebase 是异步的。我认为只要您使用时间戳或消息作为键,另一个作为字典中的值,这仍然有效。它可能会乱序填充,但您可以稍后按时间戳对其进行排序。虽然,是的,这可能不是最佳实践。

杰伊,我喜欢你的解决方案。难道你不需要也列出来吗uid_2: false

不幸的是,当用户 -> inf 和聊天 -> inf 时,这两个数据库结构似乎都增长了 n^2。