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

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

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

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

JavaScript

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

Q&A

解決済

1回答

1893閲覧

Firebase Realtime databaseからのデータ取得について (child_addedについて)

Kotolog_shun

総合スコア8

Firebase

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

JavaScript

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

0グッド

1クリップ

投稿2019/12/05 14:14

編集2019/12/05 14:15

Realtime databaseからのデータ取得について、child_addedイベントの呼び出しタイミングがいまいち理解できません。

サンプルで下記のような①社員名と②所属部署を入力するだけの簡単なアプリを作りました。

HTML

1 <h1>SampleProject for Firebase</h1> 2 3 <div> 4 <form> 5 <div class="form-group"> 6 <label for="name">氏名:</label> 7 <input type="text" class="form-control" id="name" placeholder="Name"> 8 </div> 9 <div class="form-group"> 10 <label for="group">所属:</label> 11 <input type="text" class="form-control" id="group" placeholder="Group"> 12 </div> 13 <button type="submit" class="btn btn-primary btn-block register">登録</button> 14 </form> 15 </div> 16 17 <div> 18 <ul class="list"> 19 <li class="list_item"></li> 20 </ul> 21 </div>

JavaScript

1// 1. データの登録 2const registerData = (name, group) => { 3 const userInfo = { 4 name, 5 group, 6 createdAt: firebase.database.ServerValue.TIMESTAMP, 7 } 8 firebase.database().ref('users').push(userInfo); 9 console.log('データの登録処理が行われました'); 10}; 11 12// 2. データが追加された際のリスナー (リスナーを登録する関数) 13const getData = () => { 14 $('.list_item').empty(); 15 const userData = firebase.database().ref('users').orderByChild('createdAt'); 16 userData.off('child_added'); 17 userData.on('child_added', (userSnapshot) => { 18 const userId = userSnapshot.key; 19 const snapData = userSnapshot.val(); 20 addUser(userId, snapData); 21 }); 22}; 23 24// HTML要素の挿入 25const createUserListItem = (userId, snapData) => { 26 const $list_item = $('.list_item').clone(); 27 $list_item.text(snapData.name); 28 $list_item.attr('id', `user-id-${userId}`); 29 return $list_item; 30} 31const addUser = (userId, snapData) => { 32 const $list_item = createUserListItem(userId, snapData); 33 $list_item.appendTo('.list'); 34}; 35 36 37getData(); 38 39// データ登録処理の呼び出し 40$('.register').on('click', (e) => { 41 e.preventDefault(); 42 43 const name = $('#name').val(); 44 const group = $('#group').val(); 45 46 registerData(name, group); 47 48 $('#name').val(''); 49 $('#group').val(''); 50});

単純に、社員を登録していけば1件ずつ<li>タグに囲まれた社員名を画面上に表示させていきたいのですが、例えば3件データを入力すると、2件目以降のデータが何回も<li>タグで表示されてしまいます。。。(下記に実行結果の画像リンクを貼り付けます)

リンク内容

とうぜんfirebaseの公式docもみたのですが、いまいち腹落ちせず、どなたか答えをお教えいただければ幸いです。
よろしくお願いいたします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

firebaseの問題ではなくjQueryの使い方の問題だと思います。
以下のコードを考えてみてください。

HTML

1<p>バグ再現</p> 2<button id="test">何回かクリック!</button> 3<ul class="list"> 4 <li class="list_item"></li> 5</ul>

JavaScript

1$('.list_item').empty(); 2$('#test').on('click', () => { 3 const $list_item = $('.list_item').clone(); 4 $list_item.text(`test text ${~~(Math.random()*100)}`); 5 $list_item.appendTo($('.list')); 6});

バグ再現確認

バグの再現に$('.list_item').empty();は要らないのですが、おそらく質問者さんの期待と違う動きをしていると思ったので付けておきました。chrome devtoolsのelementタブなどで、どのようにDOMが変化するかご確認ください。

投稿2019/12/06 02:31

shinji709

総合スコア805

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

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

Kotolog_shun

2019/12/06 13:00

なるほど!やっと理解できました。これでは.list_itemが倍ずつ増殖してしまいますね。。。 たいへん助かりました。ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問