【Firebase】firebaseでアカウントを作ってチャットするだけのアプリ(2)

投稿者:

前提条件

UIに凝っていたら投稿の時間が空いてしまいSEO的によろしくない為、記事を分けました。
拙稿のリンク

http://maya-pg.net/2020/10/07/firebase%e3%81%a7%e3%82%a2%e3%82%ab%e3%82%a6%e3%83%b3%e3%83%88%e3%82%92%e4%bd%9c%e3%81%a3%e3%81%a6%e3%83%81%e3%83%a3%e3%83%83%e3%83%88%e3%81%99%e3%82%8b%e3%81%a0%e3%81%91%e3%81%ae%e3%82%a2%e3%83%97/

https://maya-pg.net/2020/10/05/firebase-auth%e3%81%a7%e3%81%84%e3%81%be%e3%81%84%e3%81%a1%e7%90%86%e8%a7%a3%e3%81%a7%e3%81%8d%e3%81%a6%e3%81%84%e3%81%aa%e3%81%8b%e3%81%a3%e3%81%9f%e8%aa%8d%e8%a8%bc%e5%91%a8%e3%82%8a%e3%82%92-2/

https://maya-pg.net/2020/10/05/firebase-auth%e3%81%a7%e3%81%84%e3%81%be%e3%81%84%e3%81%a1%e7%90%86%e8%a7%a3%e3%81%a7%e3%81%8d%e3%81%a6%e3%81%84%e3%81%aa%e3%81%8b%e3%81%a3%e3%81%9f%e8%aa%8d%e8%a8%bc%e5%91%a8%e3%82%8a%e3%82%92/

https://github.com/mayarin/firebase-sample

今回追加する内容

前稿での予告通り、リアルタイムチャットを実装します。

実装を行います

テキスト他データの置き場としてCloud Firestoreを作ります。

言われるがままに作ります。

なんか下手打ってた?(´・ω・`)

できた。中身にデータを格納するのは実装で行います。

https://firebase.google.com/docs/firestore/manage-data/add-data

公式を参照しながら、やはり利用するjs群に以下を追加します。

<script src="/__/firebase/7.22.0//firebase-firestore.js"></script>

プロフィール更新フォームにいったん退いてもらって、こんなフォームにしました。

            <div id='chat_area'>
              <div id='chat_window'></div>
              <form id='chat_form'>
                <textarea class="form-control col-12" id='chat_message' placeholder='メッセージ...'></textarea>
                <button class="btn btn-primary" type='submit'>ポスト</button>
              </form>
            </div>
document.querySelector("#chat_form").addEventListener("submit", function(event) {
  var user = firebase.auth().currentUser;
  var db = firebase.firestore();
  var date = new Date();
  var datetime = date.getFullYear() + '-' +
                (date.getMonth() +1 ) + '-' +
                date.getDate() + ' ' +
                date.getHours() + ':' +
                date.getMinutes() + ':' +
                date.getSeconds() ;

  // Add a new document in collection "cities"
  db.collection("openchats").doc().set({
    uid: user.uid,    
    name: user.displayName,
    message: getElementValue('chat_message'),
    picture: user.photoURL,
    datetime : datetime
  })
  .then(function() {
    console.log("Document successfully written!");
  })
  .catch(function(error) {
    console.error("Error writing document: ", error);
  });
  event.preventDefault();
});

これらにてfirestoreに書き込まれているのを確認できました。

さてここから登録されたものをchat_windowに整形しながら取ってきます。

UI慣れないといいながらこんな感じで作りました。
ここから技を使います。

めいめいのUIのHTMLは以下のように作ってあります(CSS省略)

                <span id='any_chat_parts_template'>
                <div class='any_chat_parts chat_parts'>
                  <div class='chat_message col-6'>replace_to_message</div>
                  <div class='chat_datetime col-4'>replace_to_datetime<br>
                    <img class='profile_picture' src='./unnamed.png'><br>replace_to_name
                  </div>
                </div>
                </span>

                <span id='my_chat_parts_template'>
                <div class='my_chat_parts chat_parts'>
                  <div class='chat_message col-6'>replace_to_message</div>
                  <div class='chat_datetime col-4'>replace_to_datetime<br>
                    <img class='profile_picture' src='./unnamed.png'><br>replace_to_name </div>
                </div>
                </span>

これらをこうしてjavascriptに読み込み、画面からは削除

var any_chat_parts = getElemID('any_chat_parts_template').innerHTML;
var my_chat_parts = getElemID('my_chat_parts_template').innerHTML;

getElemID('any_chat_parts_template').remove();
getElemID('my_chat_parts_template').remove();

https://firebase.google.com/docs/firestore/query-data/listen?hl=ja

上記の通りリアルタイムアップデートを取得する箇所で以下の通りに当て嵌めます。

    query.onSnapshot(function(snapshot) {
      snapshot.docChanges().forEach(function(change) {
        console.log(change.type);
        var message = change.doc.data();
        console.log(change.doc.id);
        console.log(message.uid);

        var line = '';

        if(message.uid == user.uid){
          line = my_chat_parts;
        } else {
          line = any_chat_parts;
        }

        line = line.replace('replace_to_message', message.message);
        line = line.replace('replace_to_datetime', message.datetime);
        line = line.replace('replace_to_name', message.name);
        line = line.replace('./unnamed.png', message.picture);
        getElemID('chat_window').innerHTML += line;

      });
      getElemID('chat_window').scrollTop = getElemID('chat_window').scrollHeight;
    });

よし、ラリーっぽくなりました。

ここまで満たした仕様は以下の通り。

  • サインアップ
  • サインイン
  • サインアウト
  • パスワード再設定リンク請求
  • サインイン後プロフィール更新
  • ログインメールアドレス変更
  • ログインパスワード変更
  • アカウント削除
  • アカウント全体でのチャット

最終的に

  • さっき隠したプロフィール更新フォームをパタパタ
  • 個人間チャットを積む
  • チャットメッセージが消された際のリフレッシュを行う
  • アカウントが削除された際にチャットデータも削除

など細かい調整を行います。
なおfirebaseプロジェクトはこちら。

https://myapp-7bf76.web.app/

参考リンク

https://qiita.com/noobar/items/52d5c364a8e16b8b3fec

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String/replace

コメントを残す