2016-05-29 38 views
11

对于聊天应用程序,我遵循Firebase指南structuring data。他们建议如下所示的结构。为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": { ... } 
    } 
} 

如何构建我的用户数据,这样我可以很容易地显示所有他们的部分聊天记录的列表,并为他们的每一个显示的最后一条消息和时间戳。如果我做了以下结构:

"users": { 
    "ghopper": { 
     "name": "Gary Hopper", 
     "chats": { 
      "one: true", 
      "two": true 
     } 
    }, 
    "alovelace" { ... } 
    }, 

我可以轻松地获得每个聊天组列表针对特定用户,例如ghopper,这样做(在SWIFT):

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

但是我赢了此快照中没有lastMessage和时间戳记。我需要做什么来访问这些数据?

  • 为每个用户复制所有这些数据?即添加用户/ ghopper /聊天/ one/{“lastMessage”:“ghopper:发现中继故障原因:飞蛾。”,“时间戳”:1459361875666}
  • 为每个聊天记录查询“chats/specificGroupId”用户是(添加多个listners)的一部分?
  • 还有其他的一些方法吗?

回答

2

在你把所有的聊天记录用户在列表块,你可以这样做:

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 
     } 
    } 

我不知道我的语法多大程度上是正确的。仍在学习Firebase。但是,我认为这基本上是你的第二个建议。不知道你会得到什么数据。这将是O(2n),尽管这并不坏。

[[Update 1]]

我正在懒我的代码。我把lastMessage = snapshot保存起来,以便将它添加到下一个块的字典中。

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

周杰伦,我喜欢你的解决方案。你不需要也列出uid_2: false

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

+0

因为您没有使用该变量,lastMesssage = snapshot的功能是什么?另外,在块中使用self.variable名称是最好的做法(闭包)。另外,第一个ref.child中的ref.child是重复的,所以它会读取相同的数据。最大的问题是Firebase是异步的,并且紧密的for循环将比观察块内的数据可以返回的方式运行快得多,所以我认为我们遇到了一些数据完整性问题 - 可能应该让Firebase做到这一点'东西'异步。 – Jay

+0

要回答您的答案....不,不需要uid_2:false,因为它不存在,它可能默认为false(取决于它的编码)。不,数据库不会呈指数增长。如果你有10个用户和1个聊天,那么所有10个用户都在聊天,所以唯一增长的将是聊天中的用户节点(在我的答案中),如果你有1000个用户和100个聊天,每个聊天与两个用户,那仍然只有100个聊天,每个聊天都有一个有两个用户的用户节点。即使有1000个用户和1000个聊天记录,这也不算大量的数据。 – 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": { ... }, 

然后,你可以深深查询所有聊天特定用户的一部分 - 这将返回聊天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) 
    }  
}) 

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

+1

嗨周杰伦,谢谢你的回答。我已经尝试过你的解决方案,它似乎有伎俩。但是,一旦我有很多用户,这个操作不会太昂贵,考虑到我需要查看所有“聊天/”以便找到用户所属的所有聊天内容。 – Nilsymbol

+1

@Nilsymbol很高兴工作!看起来好像你没有下拉兆字节的数据,只有几百个节点和一些孩子。 Firebase的速度非常快,因此在数千个节点上进行查询的速度非常快;它甚至不会让Firebase的呼吸困难。我们已经测试过它! – Jay

+0

@Jay我理解大部分的结构,只是不明白用户如何在“聊天”儿童中表现出来。它是用户uid的数组吗?你能解释一下布尔与uid的关系吗?非常感谢! -Colbey – justColbs