【问题标题】:Reading Two Data Models from Firebase Swift从 Firebase Swift 中读取两个数据模型
【发布时间】:2020-01-28 07:02:17
【问题描述】:

我有两个模型:一个User 模型和一本书Review 模型。我在评论中的usernameUser 类型,以便我可以检索给定评论和创建它的用户。

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

用户类

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

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

【问题讨论】:

    标签: json swift firebase firebase-realtime-database denormalization


    【解决方案1】:

    不清楚这条线的预期是什么

    let user = User(dictionary: <#T##[String : AnyObject]#> ???
    

    也不确定为什么 class User: NSObject 是一个 NSObject 但这将适用于 Swift 5。

    class User { //using pure Swift, remove NSObject
        var id: String?
        var name: String?
        var email: String?
        var profileImageUrl: String?
        init(dictionary: [String: Any]) { //change AnyObject to Any
            self.id = dictionary["id"] as? String
            self.name = dictionary["name"] as? String
            self.email = dictionary["email"] as? String
            self.profileImageUrl = dictionary["profileImageUrl"] as? String
        }
    }
    

    然后在读取闭包中的 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)
    

    或者您可以将快照传递给 User 类并让它从中获取所需的任何内容

    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 循环之外,这样它就只执行一次。

    【讨论】:

    • 我更新了User。没有 NSObject 子类,我将其初始化为[String:Any]。还从 forLoop 中删除了 self.tableView.reloadData。我添加了字典 - 这与我已经拥有的字典相似 - 我没有返回任何内容。如果我从 forLoop 中删除用户,我只能读取应用程序中的数据,但当然,我没有用户,只有他们创建的评论。
    • 这行得通。必须删除电子邮件,因为当我最初设置值时它没有被创建。还需要在我的cellForRowat(_:) 中致电profileImageUrl.loadingImageUsingCache(_:)。由于我的声望点低于 15,因此我无法公开投票。但是当情况发生变化时我会的谢谢,杰
    • @David 很高兴为您提供帮助,也很高兴您将其纳入解决方案!如果答案有帮助,请务必接受它,以便它可以帮助其他人。无论代表如何,您都可以接受。见How to Accept
    • 完成。再次感谢:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多