##達成したいこと
1対1のテキストチャット画面にて、メッセージ送信時に未読状態だった各メッセージを、メッセージ取得時に既読に変換したい。
より詳細には、最新99件の未読メッセージをFirebase Real Time DBから取得し、その取得したメッセージデータの既読情報のみ書き換えたいです。
##現状の実装
// DBへの参照を持つグローバル変数 let messageRef = Database.database().reference().child("Talks")
チャット送信部分のコード
Swift
1@IBAction func sendButtonPressed(_ sender: UIButton) { 2 3 let messagesDB = messageRef.child(userID!).child(chatMateInfo.uid).child("Messages") 4 // 一部省略 5 6 let timeInterval = NSDate().timeIntervalSince1970 7 let myTimeInterval = TimeInterval(timeInterval) 8 let time = NSDate(timeIntervalSince1970: TimeInterval(myTimeInterval)) 9 let formatter = DateFormatter() 10 formatter.dateFormat = "yyyy/MM/dd HH:mm:ss" 11 let currentTime = formatter.string(from: time as Date) 12 13 let messageDictionary = ["text": messageTextField.text!, 14 "senderUid": Auth.auth().currentUser?.uid, 15 "date": currentTime, 16 "isRead": "false"] 17 18 messagesDB.childByAutoId().setValue(messageDictionary) { 19 20 // 省略 21 } 22 let chatMateMessageDB = messageRef.child(chatMateInfo.uid).child(userID!).child("Messages") 23 chatMateMessageDB.childByAutoId().setValue(messageDictionary) { (error: Error?, dateRef: DatabaseReference) in 24 // 省略 25 } 26 }
メッセージ取得画面のコード
Swift
1func retrieveMessages () { 2 3 let messagesDB = messageRef.child(userID!).child(chatMateInfo.uid).child("Messages") 4 messagesDB.observe(.childAdded) { (snapshot) in 5 6 guard let snapshotValue = snapshot.value as? Dictionary<String, String> else { return } 7 8 let dateStr = snapshotValue["date"]! 9 let formatter: DateFormatter = DateFormatter() 10 formatter.locale = Locale(identifier: "ja_JP") 11 formatter.dateFormat = "yyyy/MM/dd HH:mm:ss" 12 let formattedDate = formatter.date(from: dateStr)! 13 14 let message = MessageBox(senderUid: snapshotValue["senderUid"]!, date: formattedDate) 15 if let text = snapshotValue["text"] { 16 message.text = text 17 } else { 18 message.imageURL = snapshotValue["imageURL"]! 19 } 20 self.messageBox.append(message) 21 self.messageTableView.reloadData() 22 23 // 一部省略 24 } 25 26 // このタイミングで未読を既読に変えたい。 27 messagesDB.queryOrdered(byChild: "isRead").queryLimited(toLast: 99).queryEqual(toValue: "false").observe(.value) { (snapshot) in 28 29 var talkContent = snapshot.value as? [String: Any] 30 // ここで値が書き換わっていない。keyはあくまでランダムなメッセージIDで、isReadはvalueの中の一部だから? 31 talkContent?.updateValue("true", forKey: "isRead") 32 } 33 }
##DBの構造
やったこと、現状悩んでいること
以下のコードで最新99件の未読データメッセージを取得し、未読/既読のkey=isReadのみ値を書き換えたい(falseからtrueへ)と思っており
updateValueを用いたのですが、値が書き変わりません。おそらくkeyはあくませメッセージのIDで、isReadはdateやtextなどと同じようにvalueに一部なので以下のような書き方では値を書き換えることができないんだと思うのですが
valueの中のisReadのみにアクセスし値を書き換えるやり方がわからず苦戦しています。
情報量が多くて恐縮ですが、ご教授いただけますと幸いです。
messagesDB.queryOrdered(byChild: "isRead").queryLimited(toLast: 99).queryEqual(toValue: "false").observe(.value) { (snapshot) in var talkContent = snapshot.value as? [String: Any] // ここで値が書き換わっていない。keyはあくまでランダムなメッセージIDで、isReadはvalueの中の一部だから? talkContent?.updateValue("true", forKey: "isRead") }
##その他の情報
開発環境:
Xcode 10.1
Swift 4.2.1
あなたの回答
tips
プレビュー