Swift Firebase 获取数据到类对象
Posted
技术标签:
【中文标题】Swift Firebase 获取数据到类对象【英文标题】:Swift Firebase get Data to Class Object 【发布时间】:2019-10-15 12:53:28 【问题描述】:我想得到以下结构(Firebase 数据库的屏幕截图):
在聊天中我有聊天的 id。有子用户 ID 和 id 和 name 值的用户。 首先,我查找用户拥有并想要获取的聊天记录,然后获取 chatId 的详细信息(用户及其 id 和名称)
我在 Swift 中有以下课程:
class Chat
var chatId: String!
var userIds: [String]!
var userNames: [String]!
我有以下代码来获取详细信息,但我没有从 chatId 中获取 userIds 或 userNames:
func getChatsFromFirebase()
self.ref = Database.database().reference()
self.ref?.child("users").child(userdefaults.getUserId()).child("chats").observe(.childAdded, with: (snapshot) in
let chat = Chat()
chat.chatId = snapshot.key
chat.userIds = []
chat.userNames = []
//print(chat.chatId)
for i in 0..<self.chats.count
let usersRef = self.ref.child("chats").child(self.chats[i].chatId).child("users").observeSingleEvent(of: .value, with: (snapshot) in
let value = snapshot.value as? NSDictionary
for userid in value!.allKeys as! [String]
let usersdetailsRef = self.ref.child("chats").child(self.chats[i].chatId).child("users").child(userid).queryOrdered(byChild: "name").observeSingleEvent(of: .value, with: (snapshot) in
let value = snapshot.value as? NSDictionary
//print(value)
let id = value?["id"] as? String ?? ""
let name = value?["name"] as? String ?? ""
//print( id + ": " + name)
chat.userIds.append(id)
chat.userNames.append(name)
)
)
self.chats.append(chat)
self.tableView.reloadData()
)
我对 Firebase 主题非常陌生。有人可以在这里帮助我吗? 谢谢。
【问题讨论】:
您想要实现的究竟是什么?您是否希望通过引用聊天 ID 来获取用户名 是的,我想要来自 chatid 的用户名 @AakashDave 我有来自 Chats 的聊天 ID,并且我想要在 chatid 中给出的用户 ID 的用户名 我已经更新了答案。如果它有效,请通过接受和支持它来关闭问题。否则请告诉我 【参考方案1】:你需要先改变你的数据模型。在这种情况下,您不需要将 id
值存储在 12345
中。您已经可以获取密钥。此外,在/users/chats
中,您只需将聊天ID 保存为chat1 : IBDrbfku887BLIY
或IBDrbfku887BLIY : true
。您始终可以分别通过 value 或 key 获取它们。
在您的聊天文档中,您只需要引用用户 ID,即只需获取它们并将它们存储为 user1 和 user2。如果您的用例需要更多用户,您可以添加更多用户。
如下重新配置您的数据模型。
现在您需要 2 个对象用户和聊天,如下所示:
Users.swift
class User : NSObject
private var _name: String!
private var _username: String!
private var _userid: String!
private var _userRef: DatabaseReference!
var name: String!
get
return _name
set
_name = newValue
var username : String!
get
return _username
set
_username = newValue
var userid: String!
get
return _userid
set
_userid = newValue
var userRef: DatabaseReference!
get
return _userRef
set
_userRef = newValue
init(userid: String, userData: Dictionary<String, Any>)
self._userid = userid
_userRef = Database.database().reference().child(_userid)
if let username = userData["username"] as? String
self._username = username
if let name = userData["name"] as? String
self._name = name
Chats.swift
class Chat : NSObject
private var _chatid: String!
private var _user1: String!
private var _user2: String!
private var _chatRef: DatabaseReference!
var user1: String!
get
return _user1
set
_user1 = newValue
var user2 : String!
get
return _user2
set
_user2 = newValue
var chatid: String!
get
return _chatid
set
_chatid = newValue
var chatRef: DatabaseReference!
get
return _chatRef
set
_chatRef = newValue
init(chatid: String, chatData: Dictionary<String, Any>)
self._chatid = chatid
_chatRef = Database.database().reference().child(_chatid)
if let user = chatData["users"] as? Dictionary<String, Any>
if let user1 = user["user1"] as? String
self._user1 = user1
if let user2 = user["user2"] as? String
self._user2 = user2
这里的主要问题/或被忽视的问题是数据的类型。在 /users
中,您的 id 12345
将是 String
类型。但是当您从/chats
获取相同的内容时,它会返回为Int
。这会下载值但从不转换它。播种/测试数据时请务必小心。
要获取用户的凭据,只需通过另一个查询引用它。这是你可以做的:
var allUsers = [User]()
var allChats = [Chat]()
func viewDidLoad()
super.viewDidLoad()
fetchAllChats()
func getUser(from userId: String, completion: @escaping (User) -> Void)
Database.database().reference().child("users").child(userId).observeSingleEvent(of: .value, with: snapshot in
if let datasnap = snapshot.value as? Dictionary<String, Any>
let user = User(userid: userId, userData: datasnap)
completion(user)
)
func fetchAllChats()
Database.database().reference().child("chats").observeSingleEvent(of: .value, with: snapshot in
allChat.removeAll()
if let snapshot = snapshot.value as? Dictionary<String, Any>
for snap in snapshot
if let chatd = snap.value as? Dictionary<String, Any>
let chat = Chat(chatid: snap.key, chatData: chatd)
self.allChats.append(chat)
// collectionview.reloadData() <--------- only if required.
)
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
let chatData = allChats[indexPath.row]
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CellId, for: indexPath) as! Cell
getUser(from: chatData.user1) user in
cell.label.text = user.usernme
return cell
【讨论】:
感谢您的回答,我会检查并给您反馈 当然,如果您没有收到任何信息,请告诉我。我实际上对此进行了测试并发布了,所以我相信它应该可以工作 我必须通过 cellForRowAt 获取用户名。我想将 label.text 设置为用户名。我如何在那里获得用户名?另一部分工作正常。我得到了与 userIds 的聊天 能否通过getUser函数中的return来解决? 你有这个想法吗?以上是关于Swift Firebase 获取数据到类对象的主要内容,如果未能解决你的问题,请参考以下文章
使用 URL (Swift) 从 Firebase 获取数据
从 firebase 获取数据到 UITableViewController - swift
防止在 Swift 中使用 .childAdded 从 Firebase 获取所有数据