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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Firebase

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

1回答

3221閲覧

リアルタイムチャットのメッセージ表示順について

tatsuya-ki

総合スコア11

Firebase

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

1グッド

0クリップ

投稿2019/06/01 06:41

チャットのコメント表示順を時系列順にしたい

Firebaseを使用してWebのリアルタイムチャットを作成しています。
Firebaseが展開しているサンプルコード(Friendly Chat)をベースにしています。
二人以上でコメントを投稿すると、自分の投稿したコメントが一番最新(もっとも下)に表示されてしまいます。
ブラウザをリロードすると時系列順のコメント表示となりますが、リロードなしでも時系列順の表示にしたいです。

発生している問題・エラーメッセージ

自身の投稿コメントが最新のものとして表示されてしまい、
他の人が最新のコメントをしても、自身のコメントより古い時系列順で表示されてしまう。
キャプチャ
赤:自身のコメント
紫:他人のコメント(後からコメントしたにも関わらず、表示順が後ろになる)

該当のソースコード

JavaScript

1// Displays a Message in the UI. 2function displayMessage(id, timestamp, name, text, picUrl, imageUrl) { 3 var div = document.getElementById(id); 4 // If an element for that message does not exists yet we create it. 5 if (!div) { 6 var container = document.createElement('div'); 7 container.innerHTML = MESSAGE_TEMPLATE; 8 div = container.firstChild; 9 div.setAttribute('id', id); 10 div.setAttribute('timestamp', timestamp); 11 for (var i = 0; i < messageListElement.children.length; i++) { 12 var child = messageListElement.children[i]; 13 var time = child.getAttribute('timestamp'); 14 if (time && time > timestamp) { 15 break; 16 } 17 } 18 messageListElement.insertBefore(div, child); 19 } 20 if (picUrl) { 21 div.querySelector('.pic').style.backgroundImage = 'url(' + addSizeToGoogleProfilePic(picUrl) + ')'; 22 } 23 div.querySelector('.name').textContent = name; 24 var messageElement = div.querySelector('.message'); 25 if (text) { // If the message is text. 26 messageElement.textContent = text; 27 // Replace all line breaks by <br>. 28 messageElement.innerHTML = messageElement.innerHTML.replace(/\n/g, '<br>'); 29 } else if (imageUrl) { // If the message is an image. 30 var image = document.createElement('img'); 31 image.addEventListener('load', function() { 32 messageListElement.scrollTop = messageListElement.scrollHeight; 33 }); 34 image.src = imageUrl + '&' + new Date().getTime(); 35 messageElement.innerHTML = ''; 36 messageElement.appendChild(image); 37 } 38 // Show the card fading-in and scroll to view the new message. 39 setTimeout(function() {div.classList.add('visible')}, 1); 40 messageListElement.scrollTop = messageListElement.scrollHeight; 41 messageInputElement.focus(); 42} 43 44// Loads chat messages history and listens for upcoming ones. 45function loadMessages() { 46 // TODO 8: Load and listens for new messages. 47 var query = firebase.firestore() 48 .collection('messages') 49 .orderBy('timestamp', 'asc'); 50// .limit(12); 51 // Start listening to the query 52 query.onSnapshot(function(snapshot) { 53 snapshot.docChanges().forEach(function(change) { 54 if (change.type === 'removed') { 55 deleteMessage(change.doc.id); 56 } else { 57 var message = change.doc.data(); 58 displayMessage(change.doc.id, message.timestamp, message.name, 59 message.text, message.profilePicUrl, message.imageUrl); 60 } 61 }); 62 }); 63} 64

試したこと

Firebase上のデータベース及び、上記コードのorderByをascに変更

補足情報(FW/ツールのバージョンなど)

Firebase
Javascript

xenbeat👍を押しています

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

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

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

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

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

xenbeat

2019/06/01 07:12

各メッセージの「timestamp」を表示して確認してみましたか? したならその根拠を追記、していないならまずは確認してその結果を追記ください。
tatsuya-ki

2019/06/01 07:27

データベース上のTimestampはユーザが投稿した時間通りとなっております。 ※FirebaseのDB上のtimestampの確認結果 timestamp(赤ユーザコメント) 2019年6月1日 15:33:52 UTC+9 timestamp(紫ユーザコメント) 2019年6月1日 15:33:53 UTC+9
xenbeat

2019/06/01 20:48

> データベース上のTimestampは HTML上はどうなってますか?
tatsuya-ki

2019/06/02 01:15

html上は、下記の通りmessagesで、javascript内の関数を呼び出しています。 javascript内の関数は上記に載せたコードの通りです。 *** <!-- Messages container --> <div id="messages-card" class="mdl-card mdl-shadow--2dp mdl-cell mdl-cell--12-col mdl-cell--6-col-tablet mdl-cell--6-col-desktop"> <div class="mdl-card__supporting-text mdl-color-text--grey-600"> <div id="messages"> <span id="message-filler"></span> </div> <form id="message-form" action="#"> <div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label"> <input class="mdl-textfield__input" type="text" id="message"> <label class="mdl-textfield__label" for="message">Message...</label> </div> <button id="submit" disabled type="submit" class="mdl-button mdl-js-button mdl-button--raised mdl-js-ripple-effect"> Send </button> </form> ***
xenbeat

2019/06/02 02:49 編集

> html上は、下記の通り 言葉足らずでしたね。 Chrome DevTools( https://developers.google.com/web/tools/chrome-devtools )等で実際にレンダリングされてる内容(HTML)を確認ください。 重要なのは「div.setAttribute('timestamp', timestamp);」で設定しているtimestampの部分です。 ※既存データはクリアするなど一旦無視して、もう一度最初から試してみてください。 そして問題が起きた(順序がおかしくなった)時点のHTMLを確認してみてください。
tatsuya-ki

2019/06/02 12:16

補足ありがとうございます!! 確認したところ、自身のコメントのtimestampがnullとなっていました。 他ユーザのコメントはtimestampに時間が反映されています。 リロードすると、nullだった部分にも時間が反映されておりました。 リロード無しでnullではなく時間を反映するにはどの部分を修正すればよいのでしょうか。
xenbeat

2019/06/02 15:31

> 確認したところ、自身のコメントのtimestampがnullとなっていました。 やはりそうでしたか。これが原因ですね。 > リロード無しでnullではなく時間を反映するにはどの部分を修正すればよいのでしょうか。 回答にします。
guest

回答1

0

ベストアンサー

次の部分を修正すればご希望の動作になると思います。

change.doc.data(); ↓ change.doc.data({ serverTimestamps: 'estimate' });

少しだけ補足。サンプルコードではtimestampserverTimestampsが登録されているので
デフォルトでは、サーバーの値(サーバータイムスタンプ)がローカルで使用可能になるまで、timestampにはnullが設定され、ローカルに書き込まれます。
上記の修正により、サーバーの値がローカルで使用可能になるまで、timestampにはローカルで試算された推定値が設定され、ローカルに書き込まれます。

投稿2019/06/02 15:30

xenbeat

総合スコア4258

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

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

tatsuya-ki

2019/06/03 10:16

ありがとうございます!! ご教示頂いたとおり修正したところ、 リアルタイムに表示順が反映されるようになりました。 補足も頂き大変勉強になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問