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

研究
OLYMPUS PEN E-PL9 (c)Maya
この記事は約9分で読めます。

この記事は1年前の記事です。当時の情報、理解に基づいておりますのでご留意ください

前提条件

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

【Firebase】firebaseでアカウントを作ってチャットするだけのアプリ(1)
はじめにfirebaseシリーズに一区切りをつけます。拙稿のリンクこの後の実装予定と、それを満たす為に使うサービス自身のプロフィールの画像を追加 → Cloud Storage(この...
【Firebase】firebase authでいまいち理解できていなかった認証周りを再確認する(2)
はじめに拙稿の続き。問題はこの後。ログイン済のアカウントが自身の個人情報をアップデートする場合にアカウントの再認証が求められるのだそうです。この辺を対応します。なお利用するソースコードはこちら。対応...
【Firebase】firebase authでいまいち理解できていなかった認証周りを再確認する(1)
はじめに以前かじったfirebaseで、authでのパスワード再設定周りですごく難儀したのでした。復習してみます参考リンク(Expo.ioで試してますけどfirebase hostingに配置するhtmlか...
mayarin/firebase-sample
Contribute to mayarin/firebase-sample development by creating an account on GitHub.

今回追加する内容

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

実装を行います

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

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

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

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

Add data to Cloud Firestore  |  Firebase

公式を参照しながら、やはり利用する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();
Cloud Firestore でリアルタイム アップデートを入手する  |  Firebase

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

    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プロジェクトはこちら。

firebaseチャット試作品 - maya.pg.
firebaseチャット試作品 - maya.pg.

参考リンク

overflow:scroll/auto; を指定した要素の中身を一番下までスクロールする - Qiita
概要 LINEのようなUIで、発言のたびに自動的にスクロールを進めたい、という要件を満たします。 実装 #targetの中にどんどん発言が増えていくというイメージです。 なお、前の投稿「position:absolute;...
String.prototype.replace() - JavaScript | MDN
replace() メソッドは、pattern にマッチした文字列の一部またはすべてを replacement で置き換えた新しい文字列を返します。

コメント

タイトルとURLをコピーしました