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

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

ただいまの
回答率

88.77%

onSnapshotを使ったfirestoreの投稿を削除してしまうと、古い投稿が新たに表示されてしまう。

受付中

回答 0

投稿

  • 評価
  • クリップ 0
  • VIEW 189

sonu

score 18

現在firebaseを使用して、簡易的なLINEのようなWebアプリを作成しています。
しかし、投稿を削除すると古い投稿が一番下に表示されてしまいます。
どなたかご教示していただけないでしょうか。

不要なコードはできるだけ削ぎ落としたつもりですが、長いコードになり読みづらくなって申し訳ありません。
尚、JavaScriptファイル内の firebaseConfig 変数の中身は変更しています。

  <main id="message-area"></main>

  <footer>
    <textarea rows="5"></textarea>
    <input type="submit" value="送信" />
  </footer>

  <script src="https://www.gstatic.com/firebasejs/7.2.3/firebase-app.js"></script>
  <script src="https://www.gstatic.com/firebasejs/7.2.3/firebase-firestore.js"></script>

 <script src="js/index.js"></script>
// Your web app's Firebase configuration
var firebaseConfig = {
    apiKey: "hogehogehoge4nhAZnja30jjJS91O-xah-6xVwM",
    authDomain: "hogehoge.firebaseapp.com",
    databaseURL: "https://hogehoge.firebaseio.com",
    projectId: "hogehoge",
    storageBucket: "hogehoge.appspot.com",
    messagingSenderId: "216169927064",
    appId: "1:185169920000:web:a5c86895656b5dhogehoge",
    measurementId: "G-HOGEHOGEHO"
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);

const db = firebase.firestore();

const messageArea = document.getElementById('message-area');
const textArea = document.querySelector('textarea');
const submit = document.querySelector('input[type="submit"]');

function scrollToEnd() {
    messageArea.scrollTop = messageArea.scrollHeight;
}

submit.addEventListener('click', e => {
    e.preventDefault();

    if (textArea.value.length === 0) {
        alert('文字が入力されていません');
        return;
    }

    db.collection('message').doc().set({
        text: textArea.value,
        timestamp: firebase.firestore.FieldValue.serverTimestamp(),
    }).then(() => {
        const data = {text: textArea.value, timestamp: new Date()};
        appendDOM(data);
        scrollToEnd();
    });
});

function appendDOM(data) {
    const divContainer = document.createElement('div');
    divContainer.className = 'container';
    const pText = document.createElement('p');
    pText.textContent = data.text;
    data.timestamp = (0 + data.timestamp.getMonth()) + '月 ' + data.timestamp.getDate() + '日 ' + data.timestamp.getHours() + ':' + data.timestamp.getMinutes() + ':' + data.timestamp.getSeconds();
    const pTimestamp = document.createElement('p');
    pTimestamp.className = 'timestamp';
    pTimestamp.textContent = data.timestamp;
    const divLeftContainer = document.createElement('div');
    divLeftContainer.className = 'left-container';
    divLeftContainer.appendChild(pTimestamp);
    divLeftContainer.appendChild(pText);

    divContainer.appendChild(divLeftContainer);

    const divDeleteButton = document.createElement('div');
    divDeleteButton.className = 'delete button';
    divDeleteButton.textContent = '削除';
    divDeleteButton.addEventListener('click', () => {
        db.collection('message').doc(data.id).delete().then(() => {
            console.log('Document successfully deleted!');
        });
    });

    divContainer.appendChild(divDeleteButton);

    messageArea.appendChild(divContainer);
}

db.collection('message').orderBy('timestamp', 'desc').limit(5).onSnapshot(querySnapshot => {
    const data = [];
    for (let change of querySnapshot.docChanges()) {
        if (change.type === 'added') {
            const text = change.doc._document.proto.fields.text.stringValue;
            const timestamp = new Date(change.doc._document.proto.fields.timestamp.timestampValue);
            data.unshift({
                text: text,
                timestamp: timestamp,
                id: change.doc.id,
            });
        }  // end if
    }  // end for

    data.forEach(d => {
        appendDOM(d);
    });

    scrollToEnd();
});
#message-area, footer {
    padding: 1rem;
}
#message-area {
    border: 1px solid #ccc;
    height: 60vh;
    overflow-y: scroll;
    max-width: 640px;
    margin: 0 auto;
}
footer {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    display: flex;
    justify-content: space-between;
    max-width: 640px;
    margin: 0 auto;
}
textarea {
    width: 70%;
}
input[type="submit"] {
    width: 25%;
}
.left-container {
    display: flex;
}
.container {
    display: flex;
    justify-content: space-around;
    margin-bottom: .5rem;
    padding-bottom: .5rem;
    border-bottom: 1px solid #ccc;
}
.delete.button {
    background-color: red;
    color: #fff;
    line-height: 3;
    padding: 0 1rem;
    cursor: pointer;
}
.delete.button:hover {
    opacity: .6;
}
p.timestamp {
    margin-right: 1rem;
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

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

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

  • ただいまの回答率 88.77%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る