Json 从Firebase Swift读取两个数据模型

Json 从Firebase Swift读取两个数据模型,json,swift,firebase,firebase-realtime-database,denormalization,Json,Swift,Firebase,Firebase Realtime Database,Denormalization,我有两个模型:一个用户模型和一个书评模型。评论中我的username类型为User,因此我可以检索给定的评论以及创建它的用户 我现在可以用我的代码检索评论,但不能检索用户对象。我做错了什么 用户类 class User: NSObject { var id: String? var name: String? var email: String? var profileImageUrl: String? init(dictionary: [String:

我有两个模型:一个
用户
模型和一个
书评
模型。评论中我的
username
类型为
User
,因此我可以检索给定的评论以及创建它的用户

我现在可以用我的代码检索评论,但不能检索用户对象。我做错了什么

用户类

class User: NSObject {
    var id: String?
    var name: String?
    var email: String?
    var profileImageUrl: String?
    init(dictionary: [String: AnyObject]) {
        self.id = dictionary["id"] as? String
        self.name = dictionary["name"] as? String
        self.email = dictionary["email"] as? String
        self.profileImageUrl = dictionary["profileImageUrl"] as? String
    }
}
查看结构

struct Review {
    let id: String
    let bookName: String
    let author: String
    let review: String
    let username: User
    let createdAt: Date
    init(id: String, bookName: String, author: String, review: String, username: User, timestamp: Double) {

        self.id = id
        self.bookName = bookName
        self.author = author
        self.review = review
        self.username = username
        self.createdAt = Date(timeIntervalSince1970: timestamp / 1000)
    }
}
审查控制员

 private func fetchReviews() {
    let reviewRef = Database.database().reference().child("reviews")
    let queryRef = reviewRef.queryOrdered(byChild: "timestamp").queryLimited(toLast: 5)

    queryRef.observe(.value, with: { snapshot in

        var temporaryReviews = [Review]()

        for child in snapshot.children {
            if let childSnapshot = child as? DataSnapshot,
                let dictionary = childSnapshot.value as? [String:Any],
                let user = dictionary["user"] as? [String:Any],
                let id = user["id"] as? String,
                let name = user["name"] as? String,
                let profileImageUrl = user["profileImageUrl"] as? String,
                let url = URL(string: profileImageUrl),
                let bookName = dictionary["bookName"] as? String,
                let author = dictionary["author"] as? String,
                let review = dictionary["review"] as? String,
                let timestamp = dictionary["timestamp"] as? Double {

                let user = User(dictionary: <#T##[String : AnyObject]#> ??? // Cannot use a user object

                let review = Review(id: childSnapshot.key, bookName: bookName, author: author, review: review, username: user, timestamp: timestamp)

                DispatchQueue.main.async {
                    temporaryReviews.insert(review, at: 0)
                    self.reviews = temporaryReviews
                    self.tableView.reloadData()
                }
            }
        }
    })
}
private func fetchReviews(){
让reviewRef=Database.Database().reference().child(“reviews”)
让queryRef=reviewRef.queryOrdered(byChild:“timestamp”).queryLimited(toLast:5)
queryRef.observe(.value),带:{snapshot in
var temporaryReviews=[Review]()
对于snapshot.children中的子对象{
如果let childSnapshot=child as?DataSnapshot,
让dictionary=childSnapshot.value为?[String:Any],
将user=dictionary[“user”]设为?[String:Any],
让id=user[“id”]作为字符串,
将name=user[“name”]设为?字符串,
将profileImageUrl=user[“profileImageUrl”]设为?字符串,
设url=url(字符串:profileImageUrl),
将bookName=字典[“bookName”]设为?字符串,
让author=字典[“author”]作为字符串,
让review=dictionary[“review”]作为字符串,
将timestamp=字典[“timestamp”]设为双精度{
let user=user(字典:???//不能使用用户对象
let review=review(id:childSnapshot.key,bookName:bookName,author:author,review:review,username:user,timestamp:timestamp)
DispatchQueue.main.async{
临时审查。插入(审查,地址:0)
自我评价=临时评价
self.tableView.reloadData()
}
}
}
})
}

如果我从循环中删除用户及其关联值,我将在UI中获取数据,但在我的视图类中没有更新的
username
photoImageURL
。数据已经在Firebase中。我如何读取数据和用户?

不清楚这一行的预期内容

let user = User(dictionary: <#T##[String : AnyObject]#> ???
然后,在读取闭包中的Firebase数据时,创建要填充用户类的项的字典

let id = user["id"] as? String,
let name = user["name"] as? String,
let profileImageUrl = user["profileImageUrl"] as? String,
let url = URL(string: profileImageUrl),

let dict: [String: Any] = [
    "id": id,
    "name": name,
    "email": email,
    "profileImageUrl": profileImageUrl
]

let aUser = User(dictionary: dict)
或者,您可以将快照传递给用户类,让它从中获取所需的任何内容

class User {
    var user_id = ""
    var name = ""
    var email = ""
    var profileImageUrl = ""

    init(withSnap: DataSnapshot) {
        self.user_id = withSnap.childSnapshot(forPath: "id").value as? String ?? "No Id"
        self.name = withSnap.childSnapshot(forPath: "name").value as? String ?? "No name"
        self.email = withSnap.childSnapshot(forPath: "email").value as? String ?? "No email"
        self.profileImageUrl = withSnap.childSnapshot(forPath: "profileImageUrl").value as? String ?? "No url"
    }
}
然后

let aUser = User(withSnap: snapshot)

另外,在代码中,每次循环迭代都会重新加载tableView,这可能会导致闪烁。最好的办法是将
self.tableView.reloadData()
移动到for循环之外,这样它只执行一次。

我更新了
用户
。没有NSObject子类,我初始化了它
[字符串:Any]
。还从forLoop中删除了
self.tableView.reloadData
。我添加了字典-这与我已经拥有的字典类似-并且我什么也不返回。如果我从forLoop中删除用户,我只能读取应用程序中的数据,但是,当然,我没有用户,只有他们创建的评论。这很有效。我必须按原样删除电子邮件初始设置值时未创建。还需要调用my
cellForRowat(:)中的
profileImageUrl.loadingImageUsingCache(:)
。我不能公开投票,因为我的声望低于15分。但如果情况发生变化,我会的,谢谢,Jay@David很高兴能提供帮助,也很高兴您将其转化为解决方案!如果答案有帮助,请务必接受它,以便它能够帮助其他人。您可以接受,无论代表如何。请参阅“完成”。再次感谢:)
let aUser = User(withSnap: snapshot)