2016-05-29 40 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