質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Objective-C

Objective-Cはオブジェクト指向型のプログラミング言語のひとつです。C言語をベースにSmalltalkが取り入れられています。

Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

0回答

880閲覧

【Swift】Firebaseからデータ取得時の重複について

ishiishiyay

総合スコア33

Objective-C

Objective-Cはオブジェクト指向型のプログラミング言語のひとつです。C言語をベースにSmalltalkが取り入れられています。

Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2020/03/29 09:02

LINEのようなメッセージアプリを開発しています。どうかお力添えを願います。

Firebaseからメッセージを取得し、Custom Classに代入し、Table Viewに表示させています。既存メッセージの取得および新着メッセージの取得は問題なくできますが、既存メッセージに紐づく情報(既読の有無)に変更があった際に、それをリアルタイムで反映できず困っています。

まず以下コードを記載していました。

Swift

1Database.database().reference().child("user-messages").child(uid!).observe(.childAdded, with: { (snapshot) in 2 let messageId = snapshot.key 3 DBProvider.Instance.mediaMessagesRef.child(messageId).observe(.value, with: {[weak self] (snapshot) in 4 //中略 5self?.messages.append(newContact);

Swift

1class Message { 2 //read以外の変数は省略 3 private var _read = false 4 init(read: Bool) { 5 _read = read 6 } 7 var read: Bool? { 8 return _read; 9 } 10} 11

この場合、ステータスが変更されたメッセージだけダブりが生じてしまいます。既存メッセージを読み込む際に一度messagesクラスがappendされ、そのあと既読ステータスが変わると、同じメッセージが重複表示されてしまいます。重複のうち、新たに重複表示された方のメッセージには既読表示がされ、最初から読み込めていたメッセージには既読表示がされていません。これはobserve(.value, を使っているため、変更された箇所だけを再度読み込んで新たにappendしてしまっているのが原因のように思います。

試したこと

.valueをやめて、singleEvent方式に変更しました。

Swift

1Database.database().reference().child("user-messages").child(uid!).observe(.childAdded, with: { (snapshot) in 2 let messageId = snapshot.key 3 DBProvider.Instance.mediaMessagesRef.child(messageId).observeSingleEvent(of: .value, with: { [weak self] (snapshot) in

これにより既存+新着メッセージは今までどおり読み込めて、既存メッセージの既読ステータスに変更があったとしても重複表示は解消されました。ただ既読メッセージのステータスに変更があった際に、messages配列にその変更を反映できていないため、table view上で既読を表示ができず困りました。

そこで、childChangeの追記も試みました。変更があったnodeの情報だけを取得し、messages配列の特定メッセージをピンポイントで探し出し上書きするという方法です。ただ、childChangeの場合は変更した箇所の「read 1」というデータしか取得できかったため意味がなかったです。

Swift

1 DBProvider.Instance.mediaMessagesRef.child(messageId).observe(.childChanged) { [weak self](snapshot) in 2 print("itemchanged") 3 print(snapshot) // Snap (read) 1 4 if let d2 = snapshot.value as? [String:AnyObject]{ 5print("成功") //出力されず 6 let timeStamp = d2["timeStamp"] as? NSNumber 7 self?.messages.filter{$0.timeStamp == timeStamp}.first?._read = true 8

何か良い方法をご存知でしたら、アドバイス頂けますと幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問