如何使用Firebase将帖子连接到用户并显示该用户并在TableView的自定义单元中发布数据

时间:2019-01-27 15:40:41

标签: ios firebase post denormalization

我正在构建一个社交媒体应用程序,由于我自己无法解决此问题,因此我需要帮助。

我已经将我的Xcode项目连接到Firebase,并使我的用户可以注册/登录并发布到Firebase的帖子,然后将这些帖子一起显示在一组TableView中,但没有任何数据连接到用户哪个张贴那个帖子。想法是,它看起来类似于Instagram帖子,但我应用中的每个帖子都必须仅包含:Photo和Caption(可选),它们是Post类的一部分,而CraftName是User类的一部分。我认为问题出在“非规范化”和不正确的tableView填充。

这是我的Firebase树的照片,当前有2位用户登录。一个发布了1个帖子,另一个发布了2个帖子

https://i.imgur.com/fc2LEMk.jpg

我已成功将Users(带有电子邮件,用户名和CraftName)注册到了Firebase数据库,并且使他们能够登录和注销,因此我认为问题仍然存在。我还可以将包含Photo和Caption的Post发布到Firebase,并用这两个对象填充tableView。剩下的唯一事情就是将用户与其Post关联起来,并在显示Post的同时,在Post上方以TextView的形式提供该用户的CraftName。

这是用于注册的AuthService类

static func register(username: String, email: String, password: String, craftName: String, onSuccess: @escaping () -> Void, onError: @escaping (_ errorMessage: String?) -> Void) {
    Auth.auth().createUser(withEmail: email, password: password, completion:  { (user, error) in
        if error != nil {
            onError(error!.localizedDescription)

            return
        }
        let uid = Auth.auth().currentUser!.uid

        self.setUserInformation(username: username, email: email,  craftName: craftName, uid: uid, onSuccess: onSuccess)

    })
}

这是注册课程

@IBAction func registerButtonPressed(_ sender: Any) {
    view.endEditing(true)
    AuthService.register(username: usernameTextField.text!, email: emailTextField.text!, password: passwordTextField.text!, craftName: craftNameTextField.text!, onSuccess: {
        self.performSegue(withIdentifier: "registerToTabBar", sender: self)
    }, onError: {error in
         ProgressHUD.showError(error!)
        })
    }
}

//Stvaranje reference na Firebase Realtime bazu podataka i spremanje svih podataka svakog korisnika zasebno u tu bazu podataka
static func setUserInformation(username: String, email: String, craftName: String, uid: String, onSuccess: @escaping () -> Void){

    let ref = Database.database().reference()
    let usersReference = ref.child("users")
    let newUserReference = usersReference.child(uid)
    newUserReference.setValue(["username": username, "email": email, "craftName": craftName])

    onSuccess()
}

}

这是我的用户类别

struct User {
    var username: String?
    var email: String?
    var craftName: String

    init(craftNameString: String, emailString : String, usernameString: String){
        craftName = craftNameString
        username = usernameString
        email = emailString
    }
}

这是我的邮政课

class Post {

    var caption: String?
    var photoUrl: String?
    var numberOfClaps: Int?

    init(captionText: String, photoUrlString: String) {
        caption = captionText
        photoUrl = photoUrlString     
    }
}

这是我的Post自定义单元格类

class PostCell: UITableViewCell {

    @IBOutlet weak var postImageView: UIImageView!

    @IBOutlet weak var captionTextViev: UITextView!

    @IBOutlet weak var craftNameTextField: UITextView!

    var post : Post! {
        didSet{
            self.updatePostUI()
        }
    }
    var user : User! {
        didSet{
            self.updateUserUI()
        }
    }

    func updatePostUI() {

        captionTextViev.text = post.caption

    }
    func updateUserUI(){
        craftNameTextField.text = user.craftName
    }
 }

现在,当我的用户注册后,他们可以在CameraClass中发布帖子。

@IBAction func shareButtonPressed(_ sender: Any) {
    if let postImg = selectedImage, let imageData = postImg.jpegData(compressionQuality: 1) {
        let photoIDString = NSUUID().uuidString
        print(photoIDString)
        let storageRef = Storage.storage().reference(forURL: Config.STORAGE_ROOT_REF).child("posts").child(photoIDString)

        storageRef.putData(imageData, metadata: nil, completion: { (metadata, error) in
            if error != nil {
                ProgressHUD.showError(error?.localizedDescription)
                return
            }
            storageRef.downloadURL(completion: { (url, error) in
                    if error != nil {
                        ProgressHUD.showError(error!.localizedDescription)
                    }else {

                        if let photoURL = url?.absoluteString{
                            self.sendDataToDatabase(photoUrl: photoURL)
                        }
                    }
                })
            })
        }
    }


func sendDataToDatabase(photoUrl: String) {
    let ref = Database.database().reference()
    let uid = Auth.auth().currentUser!.uid
    let postsReference = ref.child("posts")
    let userUID = postsReference.child(uid)
    let newPostID = userUID.child(userUID.childByAutoId().key!)
    newPostID.setValue(["photoUrl": photoUrl, "caption": captionTextView.text!], withCompletionBlock: { (error, ref) in
        if error != nil {
            ProgressHUD.showError(error!.localizedDescription)
            return
        }
        ProgressHUD.show("Uspješno ste objavili fotografiju")
        ProgressHUD.dismiss()
        self.clean()

        self.tabBarController?.selectedIndex = 0
    })

这是我的HomeViewController,其中应该是显示帖子的tableView

class HomeViewController: UIViewController {

@IBOutlet weak var tableView: UITableView!
var posts = [Post]()

struct Storyboard {

    static let postCellDefaultHeight : CGFloat = 578.0
}

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.dataSource = self

    tableView.estimatedRowHeight = Storyboard.postCellDefaultHeight
    tableView.rowHeight = UITableView.automaticDimension
    tableView.separatorColor = UIColor.clear
    loadPosts()
}

//Function which is supposed to retrieve data from database and populate the TableView
func loadPosts() {

            let ref = Database.database().reference()
            let posts = ref.child("posts")
            posts.observe(.value) { (snapshot) in
                    for currentUser in (snapshot.children) {
                        let cUSer = currentUser as! DataSnapshot
                        for postInfo in (cUSer.children) {
                            let postSnap = postInfo as! DataSnapshot
                            let dict = postSnap.value as? [String: Any]
                            let captionText = dict!["caption"] as! String
                            let photoUrlString = dict!["photoUrl"] as! String
                            let post = Post(captionText: captionText, photoUrlString: photoUrlString)

                            self.posts.append(post)
                            self.tableView.reloadData()
                        }
                    }
                }
            }

现在看起来像这样: https://i.imgur.com/lMxZYLW.jpg

这就是我想要的样子: https://i.imgur.com/721mEXm.jpg

0 个答案:

没有答案