現在GoogleのFirebaseを用いてJavaScriptの勉強をしているのですが、Firebaseへのデータの登録はできたのですが、削除がうまくいきません。
リファレンスは確認しましたが、理解が及ばないためご助力願います。
コメントを見ていただければ分かると思いますが、サンプルからここまで作成しています。
JavaScript
1/* jshint curly:true, debug:true */ 2/* globals $, firebase */ 3 4/** 5 * ------------------- 6 * 書籍一覧画面関連の関数 7 * ------------------- 8 */ 9 10// 書籍の表紙画像をダウンロードする 11const downloadBookImage = bookImageLocation => firebase 12 .storage() 13 .ref(bookImageLocation) 14 .getDownloadURL() // book-images/abcdef のようなパスから画像のダウンロードURLを取得 15 .catch((error) => { 16 console.error('写真のダウンロードに失敗:', error); 17 }); 18 19// 書籍の表紙画像を表示する 20const displayBookImage = ($divTag, url) => { 21 $divTag.find('.book-item__image').attr({ 22 src: url, 23 }); 24}; 25 26 27!!実装したいのはここ!!→実装できました 28// Realtime Database の books から書籍を削除する 29const deleteBook = (bookId) => { 30 // TODO: books から該当の書籍データを削除 31 if(window.confirm('削除してよろしいですか?')){ 32 return firebase 33 .database() 34 .ref(`books/${bookId}`) 35 .remove(); 36 // キャンセル時の処理 37 } else { 38 return; 39 } 40}; 41 42 43 44// 書籍の表示用のdiv(jQueryオブジェクト)を作って返す 45const createBookDiv = (bookId, bookData) => { 46 // HTML内のテンプレートからコピーを作成する 47 const $divTag = $('#book-template > .book-item').clone(); 48 49 // 書籍タイトルを表示する 50 $divTag.find('.book-item__title').text(bookData.bookTitle); 51 52 // 書籍の表紙画像をダウンロードして表示する 53 downloadBookImage(bookData.bookImageLocation).then((url) => { 54 displayBookImage($divTag, url); 55 }); 56 57 // id属性をセット 58 $divTag.attr('id', `book-id-${bookId}`); 59 60 // 削除ボタンのイベントハンドラを登録 61 const $deleteButton = $divTag.find('.book-item__delete'); 62 $deleteButton.on('click', () => { 63 deleteBook(bookId); 64 }); 65 return $divTag; 66}; 67 68// 書籍一覧画面内の書籍データをクリア 69const resetBookshelfView = () => { 70 $('#book-list').empty(); 71}; 72 73// 書籍一覧画面に書籍データを表示する 74const addBook = (bookId, bookData) => { 75 const $divTag = createBookDiv(bookId, bookData); 76 $divTag.appendTo('#book-list'); 77}; 78 79// 書籍一覧画面の初期化、イベントハンドラ登録処理 80const loadBookshelfView = () => { 81 resetBookshelfView(); 82 83 // 書籍データを取得 84 const booksRef = firebase 85 .database() 86 .ref('books') 87 .orderByChild('createdAt'); 88 89 // 過去に登録したイベントハンドラを削除 90 booksRef.off('child_removed'); 91 booksRef.off('child_added'); 92 93 // books の child_removedイベントハンドラを登録 94 // (データベースから書籍が削除されたときの処理) 95 booksRef.on('child_removed', (bookSnapshot) => { 96 const bookId = bookSnapshot.key; 97 const $book = $(`#book-id-${bookId}`); 98 99 !!!実装したい!!! 100 // TODO: 書籍一覧画面から該当の書籍データを削除する 101 102 }); 103 104 // books の child_addedイベントハンドラを登録 105 // (データベースに書籍が追加保存されたときの処理) 106 booksRef.on('child_added', (bookSnapshot) => { 107 const bookId = bookSnapshot.key; 108 const bookData = bookSnapshot.val(); 109 110 // 書籍一覧画面に書籍データを表示する 111 addBook(bookId, bookData); 112 }); 113}; 114 115/** 116 * ---------------------- 117 * すべての画面共通で使う関数 118 * ---------------------- 119 */ 120 121// ビュー(画面)を変更する 122const showView = (id) => { 123 $('.view').hide(); 124 $(`#${id}`).fadeIn(); 125 126 if (id === 'bookshelf') { 127 loadBookshelfView(); 128 } 129}; 130 131/** 132 * ------------------------- 133 * ログイン・ログアウト関連の関数 134 * ------------------------- 135 */ 136 137// ログインフォームを初期状態に戻す 138const resetLoginForm = () => { 139 $('#login__help').hide(); 140 $('#login__submit-button') 141 .prop('disabled', false) 142 .text('ログイン'); 143}; 144 145// ログインした直後に呼ばれる 146const onLogin = () => { 147 console.log('ログイン完了'); 148 149 // 書籍一覧画面を表示 150 showView('bookshelf'); 151}; 152 153// ログアウトした直後に呼ばれる 154const onLogout = () => { 155 const booksRef = firebase.database().ref('books'); 156 157 // 過去に登録したイベントハンドラを削除 158 booksRef.off('child_removed'); 159 booksRef.off('child_added'); 160 161 showView('login'); 162}; 163 164/** 165 * ------------------ 166 * イベントハンドラの登録 167 * ------------------ 168 */ 169 170// ログイン状態の変化を監視する 171firebase.auth().onAuthStateChanged((user) => { 172 // ログイン状態が変化した 173 if (user) { 174 // ログイン済 175 onLogin(); 176 } else { 177 // 未ログイン 178 onLogout(); 179 } 180}); 181 182// ログインフォームが送信されたらログインする 183$('#login-form').on('submit', (e) => { 184 e.preventDefault(); 185 186 const $loginButton = $('#login__submit-button'); 187 $loginButton.text('送信中…'); 188 189 const email = $('#login-email').val(); 190 const password = $('#login-password').val(); 191 192 // ログインを試みる 193 firebase 194 .auth() 195 .signInWithEmailAndPassword(email, password) 196 .then(() => { 197 // ログインに成功したときの処理 198 console.log('ログインしました。'); 199 200 // ログインフォームを初期状態に戻す 201 resetLoginForm(); 202 }) 203 .catch((error) => { 204 // ログインに失敗したときの処理 205 console.error('ログインエラー', error); 206 207 $('#login__help') 208 .text('ログインに失敗しました。') 209 .show(); 210 211 // ログインボタンを元に戻す 212 $loginButton.text('ログイン'); 213 }); 214}); 215 216// ログアウトボタンが押されたらログアウトする 217$('.logout-button').on('click', () => { 218 firebase 219 .auth() 220 .signOut() 221 .catch((error) => { 222 console.error('ログアウトに失敗:', error); 223 }); 224}); 225 226/** 227 * ------------------------- 228 * 書籍情報追加モーダル関連の処理 229 * ------------------------- 230 */ 231 232// 書籍の登録モーダルを初期状態に戻す 233const resetAddBookModal = () => { 234 $('#book-form')[0].reset(); 235 $('#add-book-image-label').text(''); 236 $('#submit_add_book') 237 .prop('disabled', false) 238 .text('保存する'); 239}; 240 241// 選択した表紙画像の、ファイル名を表示する 242$('#add-book-image').on('change', (e) => { 243 const input = e.target; 244 const $label = $('#add-book-image-label'); 245 const file = input.files[0]; 246 247 if (file != null) { 248 $label.text(file.name); 249 } else { 250 $label.text('ファイルを選択'); 251 } 252}); 253 254// 書籍の登録処理 255$('#book-form').on('submit', (e) => { 256 e.preventDefault(); 257 258 // 書籍の登録ボタンを押せないようにする 259 $('#submit_add_book') 260 .prop('disabled', true) 261 .text('送信中…'); 262 263 // 書籍タイトル 264 const bookTitle = $('#add-book-title').val(); 265 266 const $bookImage = $('#add-book-image'); 267 const { files } = $bookImage[0]; 268 269 if (files.length === 0) { 270 // ファイルが選択されていないなら何もしない 271 return; 272 } 273 274 const file = files[0]; // 表紙画像ファイル 275 const filename = file.name; // 画像ファイル名 276 const bookImageLocation = `book-images/${filename}`; // 画像ファイルのアップロード先 277 278 // 書籍データを保存する 279 firebase 280 .storage() 281 .ref(bookImageLocation) 282 .put(file) // Storageへファイルアップロードを実行 283 .then(() => { 284 // Storageへのアップロードに成功したら、Realtime Databaseに書籍データを保存する 285 const bookData = { 286 bookTitle, 287 bookImageLocation, 288 createdAt: firebase.database.ServerValue.TIMESTAMP, 289 }; 290 return firebase 291 .database() 292 .ref('books') 293 .push(bookData); 294 }) 295 .then(() => { 296 // 書籍一覧画面の書籍の登録モーダルを閉じて、初期状態に戻す 297 $('#add-book-modal').modal('hide'); 298 resetAddBookModal(); 299 }) 300 .catch((error) => { 301 // 失敗したとき 302 console.error('エラー', error); 303 resetAddBookModal(); 304 $('#add-book__help') 305 .text('保存できませんでした。') 306 .fadeIn(); 307 }); 308}); 309
やりたいことは、削除ボタンが押されたら、そのデータのみをDBから削除してページを更新したいのですが、上記のようにremove(bookId.bookTitle)として削除ボタンを押すと、なぜかテーブル内の全データが削除されます。(bookIdだけではエラーが出てしまい、削除されませんでした)→できました。
console.logで確認しましたが、bookIdは取得できています。→できました。
また、削除後に該当のデータを表示している一覧からもデータを削除して再表示させたいのですが、削除ボタン押下後に更新されないため自分でページ更新をしないと反映されません。ファイルを保存するときは、保存後にページがリロードされる?のですが、その処理がどこに当たるのかが分かりません。
削除後にページを更新する、またはhtmlから該当データを削除する方法について教えて頂けないでしょうか。よろしくお願いします。
あなたの回答
tips
プレビュー