firebase消息意外地发现没有

时间:2017-06-03 02:27:15

标签: ios firebase firebase-realtime-database tableview

我有一个tableviewcontroller,其中包含已登录用户在应用中向其选择的所有用户发送的所有消息的列表:

使用此代码附加登录用户与应用程序的任何其他用户之间的消息并显示在tableviewcell中:

func loadData()
{

    FIRDatabase.database().reference().child("messages").observeSingleEvent(of: .value, with: { (snapshot:FIRDataSnapshot) in

        if let postsDictionary = snapshot .value as? [String: AnyObject] {

            for post in postsDictionary {
                let messages = post.value as! [String: AnyObject]
                for (id, value) in messages {
                    let info = value as! [String: AnyObject]


                    let convoId = info["convoId"]
                    let toId = info["ReceiverId"] as! String!
                    let fromId = info["senderId"] as! String!


                    if (toId == self.loggedInUserUid  || fromId == self.loggedInUserUid) {

    let ref = FIRDatabase.database().reference().child("messages").child(convoId as! String)
    ref.observe(.childAdded, with: { (snapshot) in



        if let dictionary = snapshot.value as? [String: AnyObject] {
            let message = Message(dictionary: dictionary)
            //                self.messages.append(message)

            if let receiver = message.convoId {
                self.messagesDictionary[receiver] = message

                self.messages = Array(self.messagesDictionary.values)
                print(self.messages)
                self.messages.sort(by: { (message1, message2) -> Bool in


                    return (message1.timestamp?.int32Value)! > (message2.timestamp?.int32Value)!

                })
            }

            //this will crash because of background thread, so lets call this on dispatch_async main thread
            DispatchQueue.main.async(execute: {
                self.MessageTableView.reloadData()
            })
        }

    }, withCancel: nil)}
                }

            }}})

}

但是,当我单击一个单元格时,我想转到一个详细的视图控制器,它显示登录用户和单击的单元用户之间的消息,因此我使用此代码进行划分:

 override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

             let message = messages[indexPath.row]

            if message.ReceiverId != self.loggedInUserUid {
                var newVariable = message.ReceiverId


                if let userpicuid =  newVariable {

                    let ref = FIRDatabase.database().reference().child("users").child(userpicuid)

                    ref.observeSingleEvent(of: .value, with: { (snapshot)
                        in

                        if let dictionary = snapshot.value as? [String: AnyObject]{
                            for post in dictionary {
                                let messages = post.value as! [String: AnyObject]
                                for (id, value) in messages {

                                    let username = messages["username"] as? String
                                    self.userpicuid = userpicuid
                                    self.username = username


                                }}}})}} else if message.senderId != self.loggedInUserUid {
                let newVariable = message.senderId

                if let userpicuid =  newVariable {

                    let ref = FIRDatabase.database().reference().child("users").child(userpicuid)

                    ref.observeSingleEvent(of: .value, with: { (snapshot)
                        in

                        if let dictionary = snapshot.value as? [String: AnyObject]{
                            for post in dictionary {
                                let messages = post.value as! [String: AnyObject]
                                for (id, value) in messages {

                                    let username = messages["username"] as? String
                                    self.userpicuid = userpicuid
                                    self.username = username
                                }}}})}

            }

       performSegue(withIdentifier: "MessageNow", sender: self)

    }


    override public func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        guard segue.identifier == "MessageNow", let chatVc = segue.destination as? SendMessageViewController else {
            return
        }

        print(self.userpicuid)

        chatVc.senderId = self.loggedInUser?.uid
        chatVc.receiverData = self.userpicuid 
        chatVc.senderDisplayName = self.userpicuid
        chatVc.username = self.username

    }

然而,当我点击单元格时,我收到错误致命错误:在展开可选值时意外发现nil 所以我包含了一些打印语句以找出nil的位置。结果是userpicuid,用户名返回nil。我不确定我做错了什么,特别是因为我的代码正在检查receiverId和senderId,并且其中一个不是登录用户的uid,那么uid应该是发送者ID,它会分割成详细消息。

错误发生在let receiverId = receiverData上!详细消息视图控制器中的行:

var receiverData: String?

     override func viewDidLoad() {
            super.viewDidLoad()
    let receiverId = receiverData!
            let receiverIdFive = String(receiverId.characters.prefix(5))
            let senderIdFive = String(senderId.characters.prefix(5))
            if (senderIdFive > receiverIdFive)
            {
                self.convoId = senderIdFive + receiverIdFive
            }
            else
            {
                self.convoId = receiverIdFive + senderIdFive
            }
    }

2 个答案:

答案 0 :(得分:0)

尝试这一行:

performSegue(withIdentifier: "MessageNow", sender: self)

就在这里:

 let username = messages["username"] as? String
 self.userpicuid = userpicuid
 self.username = username
 performSegue(withIdentifier: "MessageNow", sender: self)

答案 1 :(得分:0)

我用这个找到了问题的解决方案:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "MessageCell", for: indexPath) as! MessageTableViewCell


    if message.ReceiverId != self.loggedInUserUid {
        var newVariable = message.ReceiverId

    if let imageName =  newVariable {

        let ref = FIRDatabase.database().reference().child("users").child(imageName)

        ref.observeSingleEvent(of: .value, with: { (snapshot)
            in

            if let dictionary = snapshot.value as? [String: AnyObject]{
                for post in dictionary {
                    let messages = post.value as! [String: AnyObject]
                    for (id, value) in messages {


                        self.username = messages["username"] as? String
                        self.userpicuid = messages["uid"] as? String


            }}}})}}else if message.senderId != self.loggedInUserUid {
        let newVariable = message.senderId

        if let imageName =  newVariable {

            let ref = FIRDatabase.database().reference().child("users").child(imageName)

            ref.observeSingleEvent(of: .value, with: { (snapshot)
                in

                if let dictionary = snapshot.value as? [String: AnyObject]{
                    for post in dictionary {
                        let messages = post.value as! [String: AnyObject]
                        for (id, value) in messages {

                            self.username = messages["username"] as? String
                            self.userpicuid = messages["uid"] as? String

                        }}}})}
    }
    return cell
}


  override public func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        guard segue.identifier == "MessageNow", let chatVc = segue.destination as? SendMessageViewController else {
            return
        }


                                chatVc.senderId = self.loggedInUser?.uid
                                chatVc.receiverData = self.userpicuid
                                chatVc.senderDisplayName = self.userpicuid
                                chatVc.username = self.username




    }