Получить имя пользователя относительно пользовательского идентификатора из Firebase для отображения комментариев - PullRequest
0 голосов
/ 03 мая 2018

Я создаю коллекционное представление, содержащее комментарии, где я извлекаю комментарии, идентификатор комментария, идентификатор сообщения и идентификатор пользователя из Firebase. Когда я пытаюсь получить информацию о пользователе, связанную с идентификатором пользователя, и добавляю комментарии, это не работает. Я думаю, это потому, что я добавляю snapshot.value в пользовательскую ссылку, и поэтому у него больше нет ссылки на комментарий. Как получить как комментарий, так и имя пользователя, связанное с UID, и отобразить его в представлении коллекции комментариев?

Вот как выглядит иерархия в Firebase: Нажмите здесь.

По моему мнению, пост-контроллер, я получаю комментарии вот так.

  var comments = [Comment]()
fileprivate func fetchComments() {
    guard let postID = self.post?.id else {return}
    let commentRef = Database.database().reference().child("comments").child(postID)
    commentRef.observe(.childAdded, with: { (snapshot) in

        guard let dict = snapshot.value as? [String: Any] else {return}

        guard let uid = dict["uid"] as? String else {return}

        let userRef = Database.database().reference().child("users/\(uid)/profile")
        userRef.observe(.value, with: { snapshot in

            if (snapshot.value as? [String: Any]) != nil {
                //let snap = snapshot.value as? [String: Any]
                var comment = Comment(dictionary: dict)


                comment.user = snapshot.value as? User
                self.comments.append(comment)
                print(comment)
                self.commentCollectionView.reloadData()
                }
            })

        })
}

Настройка представления коллекции для комментариев, как это.

extension ViewPostViewController: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return comments.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "commentCell", for: indexPath) as! CommentCollectionViewCell
    cell.comment = self.comments[indexPath.item]
    return cell
}
}

My CommentsCollectionViewCell.swift имеет этот код:

class CommentCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var usernameLabel: UILabel!
@IBOutlet weak var commentLabel: UILabel!
@IBOutlet weak var timePostedLabel: UILabel!

var comment: Comment? {
    didSet {
        guard let comment = comment else {return}
        guard let username = comment.user?.username else {return}
        print(username)
        commentLabel.text = comment.comment
        usernameLabel.text = comment.user?.username
    }
}
}

Класс модели комментариев имеет этот код:

struct Comment {

var user: User?

let comment: String

let uid: String

init(dictionary: [String: Any]) {
    self.comment = dictionary["comment"] as? String ?? ""
    self.uid = dictionary["uid"] as? String ?? ""
}
}

1 Ответ

0 голосов
/ 03 мая 2018

Во-первых, я бы реорганизовал ваш код, добавив имя пользователя в корзину комментариев, чтобы сэкономить нагрузку на устройство, чтобы позже извлечь его из нескольких источников.

Это было бы довольно легко исправить. Добавьте одну или две строки кода для вашей функции saveToFirebase и одну или две строки кода для вашей функции fetchComments.

Но если вы хотите сохранить его таким, как он структурирован, я бы сделал что-то вроде:

func getComments(_ post: String, completion:  @escaping (_ info: [String?], _ error: NSError?) -> Void)  { 
    Database.database().reference.child("comments").child(postID).observeSingleEvent(of: .value) { (snapshot) in
        if let snapshots = snapshot.children.allObjects as? [DataSnapshot] {
            for snap in snapshot {
                if let dict = snap.value as? Dictionary<String, AnyObject> {
                    completion([dict["comment"],dict["uid"]],nil) // send data through handler
                } else { completion([], someError) }
            }
        } else { completion([], someError) }
    }
}


func getUserName(_ uid: String, completion:  @escaping (_ info: [String: Any]?, _ error: NSError?) -> Void)  { 
    Database.database().reference.child("users").child(uid).observeSingleEvent(of: .value) { (snapshot) in
        completion([snapshot],nil) // send data back
    } 
}

Тогда внутри вашего collectionView, когда вы устанавливаете контент, вы можете называть функции следующим образом:

        // or wherever you get your postID's from
getComments(posts[indexPath.row], completion: { (info, err) in 
    if err != nil { 
        print(err!.localizedDescription) 
    } else { 
        // info is available find user
        guard let uid = info[1] as? String? else { return }
        // do whatever else you want to with the info here 
        // like populate cell data (perform on main thread)
        getUserName(uid, completion: { (snapDict, err) in
            if err != nil {
                // handle error
            } else {
                // get Username from dictionary and do what you want with it
        }) // end getUserName
    } 
}) // end getComments
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...