在Swift中从Firebase中的多个节点获取数据

时间:2018-11-12 08:31:59

标签: swift firebase firebase-realtime-database

我构建了自己的应用,使其具有Facebook等新闻提要。我的问题是我不知道如何在images中提取子Post并将其显示在collectionView中。请告诉我该怎么做。感谢任何帮助。

这是数据库结构:

Posts
   d7j3bWMluvZ6VH4tctQ7B63dU4u1:
       20181112101928:
          avatar: "https://platform-lookaside.fbsbx.com/platform/p..."
          content: "Funny image"
          images:
              -LR4vaEIggkGekc-5ZME:
                       "https://firebasestorage.googleapis.com/v0/b/hon..."
              -LR4vaENC-IsePibQYxY:                             
                       "https://firebasestorage.googleapis.com/v0/b/hon..."
          name: "Thành Trung"
          time: 1541992768776.3628
          type: "Funny"

这是我的代码:

   func getDataFromPostFirebase() {
        let getPostData = databaseReference.child("Posts")
        getPostData.observe(.childAdded) { (snapshot) in
            getPostData.child(snapshot.key).observe(.childAdded, with: { (snapshot1) in
                getPostData.child(snapshot.key).child(snapshot1.key).observe(.value, with: { (snapshot2) in
                    self.arrayImageUrl = [String]()
                    if let dict = snapshot2.value as? [String : Any] {
                        guard let avatar = dict["avatar"] as? String else {return}
                        guard let content = dict["content"] as? String else {return}
                        guard let name = dict["name"] as? String else {return}
                        guard let time = dict["time"] as? Double else {return}
                        guard let type = dict["type"] as? String else {return}
                        if let images = dict["images"] as? [String : String] {
                            for image in images.values {
                                self.arrayImageUrl.append(image)
                            }
                            let newPost = Post(avatarString: avatar, contentString: content, nameString: name, timeDouble: time, typeString: type)
                            self.arrayPost.append(newPost)
                            DispatchQueue.main.async {
                                self.feedTableView.reloadData()
                            }
                        } else {
                            let newPost = Post(avatarString: avatar, contentString: content, nameString: name, timeDouble: time, typeString: type)
                            self.arrayPost.append(newPost)
                            DispatchQueue.main.async {
                                self.feedTableView.reloadData()
                            }
                        }
                    }
                })
            })
        }
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return arrayImageUrl.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "collectionViewCell", for: indexPath) as! TrangChu_CollectionViewCell

        cell.imgContent.layer.cornerRadius = CGFloat(8)
        cell.imgContent.clipsToBounds = true
        cell.imgContent.layer.borderWidth = 2
        cell.imgContent.layer.borderColor = #colorLiteral(red: 0.4756349325, green: 0.4756467342, blue: 0.4756404161, alpha: 1)

        let url = URL(string: arrayImageUrl[indexPath.row])
        cell.imgContent.sd_setImage(with: url, completed: nil)

        return cell
    }

模型对象

import Foundation

class Post {
    var avatar : String
    var content : String
    var images : [String]?
    var name : String
    var time : Double
    var type : String

    init(avatarString : String, contentString : String, nameString : String, timeDouble : Double, typeString : String) {
        avatar = avatarString
        content = contentString
//        images = imagesString
        name = nameString
        time = timeDouble
        type = typeString
    }
}

3 个答案:

答案 0 :(得分:2)

正如我所说,您的数据库结构不完善。我建议您像这样重新构造它。

Posts
   d7j3bWMluvZ6VH4tctQ7B63dU4u1:
      avatar: "https://platform-lookaside.fbsbx.com/platform/p..."
      content: "Funny image"
      images:
          -LR4vaEIggkGekc-5ZME: "https://firebasestorage.googleapis.com/v0/b/hon..."
          -LR4vaENC-IsePibQYxY: "https://firebasestorage.googleapis.com/v0/b/hon..."
      name: "Thành Trung"
      time: 1541992768776.3628
      type: "Funny"
      timestamp: 1540276959924

我删除了timestamp节点,并将其沿子节点转移。现在您可以以此来获取帖子。

ref.child("Posts").observe(.childAdded) { (snapshot) in
        var post = Post()

        let val = snapshot.value as! [String: Any]
        post.name = val["name"] as? String

        self.ref.child("Posts").child(snapshot.key).child("images").observeSingleEvent(of: .value, with: { (snap) in
            post.imagesString = [String]()
            for image in snap.children.allObjects as! [DataSnapshot] {
                post.imagesString?.append(image.value as! String)
                print("images \(image.value)")
            }

            list.append(post)
            print("post \(post)")
        })

如果要订购帖子,可以使用 queryOrderedByChild(“ timestamp”)

实现

答案 1 :(得分:0)

您可以使用此方法获取图像值

ref.child("Posts").observe(.childAdded) { (snapshot) in

        self.ref.child("Posts").child(snapshot.key).observe(.childAdded, with: { (snapshot1) in
            self.ref.child("Posts").child(snapshot.key).child(snapshot1.key).child("images").observe(.childAdded, with: { (snap) in
                let post = new Post()
                for rest in snap.children.allObjects as! [DataSnapshot] {
                    //append images 
                    post.imagesString.append(rest.value)
                }


                post.avatarString = snapshot1.value["avatar"] as? String
                ...
            })
        })

我建议您更改数据库的结构,因为它是嵌套的。请参阅here

答案 2 :(得分:0)

添加此项以访问您的图像:

guard let images = dict["images"] as? [[String: Any]] { return }
let imagesString: [String] = []
for imageDict in images {
    for key in imageDict.keys {
        if let imageName = imageDict[key] as? String else {
        // here you access your image as you want
            imagesString.append(imageName)
        }
    }   
}

然后在创建发布对象时,使用我们创建的imagesString

let newPost = Post(avatarString: avatar, contentString: content, imagesString: imagesString, nameString: name, timeDouble: time, typeString: type)