質問するログイン新規登録
Firebase

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

Cloud Firestore

Cloud Firestore は、自動スケーリングと高性能を実現し、アプリケーション開発を簡素化するように構築された NoSQLドキュメントデータベースです。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

0回答

338閲覧

[firestore] [react] useCollectionDataでデータを取り出す際docIdがいつの間にかundefiedになっていた

DaisukeMori

総合スコア229

Firebase

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

Cloud Firestore

Cloud Firestore は、自動スケーリングと高性能を実現し、アプリケーション開発を簡素化するように構築された NoSQLドキュメントデータベースです。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2022/05/13 17:22

0

0

昔実装したReact + Firestoreの登録・削除機能を久しぶりに実装してみたところ登録は以前のようにできたのですが、削除が一向にされないという不具合が発生しました。

その原因を追求したところどうやらuseCollectionDataで呼び出し,
console.log(list.docId);docIdを出そうしたところ何故かundefiedになってしまいます。
docIdundefiedになるがゆえに
<div className="delete" onClick={() => handleDelete(item.docId)}>Delete</div>docIdが渡せず、削除が行われなくなっています。
数年前確実にdocIdが取得できておりもちろん削除も正常に行われていました。
この数年のうちにFirestore側で変更あったのでしょうか?
そしてFirestoreのdocIdを取得する方法を教えていただきたいです。

uploadのコード全文載せておきます。

jsx

1import { useState } from 'react'; 2import firebase, { storage, db } from '../../Firebase'; 3import { useForm } from 'react-hook-form'; 4import { useCollectionData } from 'react-firebase-hooks/firestore'; 5 6const Upload = () => { 7 // Create 8 const [msg, setMsg] = useState(''); 9 const [pending,setPending] = useState(false); 10 // Upload 11 const [image, setImage] = useState(''); 12 const [imageUrl, setImageUrl] = useState(''); 13 14 const { handleSubmit } = useForm(); 15 16 // auth user 17 const user = firebase.auth().currentUser; 18 let authId; 19 let email; 20 let name; 21 let photoURL; 22 if (user != null) { 23 user.providerData.forEach(() => { 24 authId = user.uid; 25 email = user.email; 26 name = user.displayName; 27 photoURL = user.photoURL; 28 }); 29 } 30 31 // Create 32 const createdAt = firebase.firestore.FieldValue.serverTimestamp(); 33 const OnSubmit = async () => { 34 setMsg(''); 35 setImageUrl(''); 36 setPending(true); 37 try { 38 await firebase 39 .firestore() 40 .collection('posts') 41 .add({ 42 msg, 43 createdAt, 44 imageUrl, 45 // 以下firebase.auth().currentUser情報 46 authId, 47 email, 48 name, 49 photoURL 50 }); 51 } finally { 52 setPending(false); 53 } 54 } 55 56 // Render 57 const [ list, loading, error ] = useCollectionData(db.collection('posts').orderBy('createdAt', 'desc'), { idField: 'docId' }); 58 console.log(list.docId); // undefiedになってしまう 59 60 if (loading) return <div>Loading...</div>; 61 if (error) return <div>Error...</div>; 62 63 const result = Object.keys(list).length; // Countを数える 64 console.log(result); 65 66 // Delete 67 const handleDelete = (uid) => { 68 if (window.confirm('削除しますか?')) { 69 db.collection('posts').doc(uid).delete(); 70 } 71 } 72 73 // File upload 74 const handleImage = e => { 75 const image = e.target.files[0]; 76 setImage(image); 77 } 78 const onSubmit = e => { 79 e.preventDefault(); 80 if (image === '') { 81 console.log('ファイルが選択されていません'); 82 } 83 const uploadTask = storage.ref(`/images/${image.name}`).put(image); 84 uploadTask.on( 85 firebase.storage.TaskEvent.STATE_CHANGED, 86 next, 87 uploadError, 88 complete 89 ); 90 } 91 const next = snapshot => { 92 const percent = (snapshot.bytesTransferred / snapshot.totalBytes) * 100; 93 console.log(percent + '% done'); 94 console.log(snapshot); 95 } 96 const uploadError = error => { 97 console.log(error); 98 } 99 const complete = () => { 100 storage 101 .ref('images') 102 .child(image.name) 103 .getDownloadURL() 104 .then(fireBaseUrl => { 105 setImageUrl(fireBaseUrl); 106 }); 107 } 108 109 return ( 110 <> 111 <form onSubmit={handleSubmit(OnSubmit)}> 112 <textarea 113 value={ msg } 114 onChange={ e => setMsg(e.target.value) } 115 placeholder="コメント" 116 name="msg" 117 > 118 </textarea> 119 {imageUrl && ( 120 <> 121 <input 122 type="hidden" 123 value={imageUrl} 124 onChange={ e => setImageUrl(e.target.value) } 125 name="image" 126 /> 127 </> 128 )} 129 <button type="submit">投稿</button> 130 { pending && 'Pendeing...' } 131 </form> 132 133 <form onSubmit={onSubmit}> 134 <input type="file" onChange={handleImage} /> 135 <button>Upload</button> 136 </form> 137 {imageUrl && ( 138 <> 139 <img src={imageUrl} id="imgSample" alt="uploaded" /> 140 </> 141 )} 142 143 {list.map(item => ( 144 <div key={item.docId + String(new Date())}> 145 {authId === item.authId ? ( 146 <> 147 {item.name ? ( 148 <div>{item.name}</div> 149 ) : ( 150 <div>ゲストユーザー</div> 151 )} 152 <div> 153 <div>{item.msg}</div> 154 {/* docIdがundefiedになるため削除できない */} 155 <div className="delete" onClick={() => handleDelete(item.docId)}>Delete</div> 156 </div> 157 {item.imageUrl && ( 158 <img src={item.imageUrl} alt="イメージ画像" /> 159 )} 160 {item.photoURL ? ( 161 <img src={ item.photoURL } alt="ユーザー画像" /> 162 ) : ( 163 <div>no image</div> 164 )} 165 </> 166 ) : ( 167 <> 168 <div> 169 {item.name ? ( 170 <div>{item.name}</div> 171 ) : ( 172 <div>ゲストユーザー</div> 173 )} 174 <div> 175 <div>{item.msg}</div> 176 </div> 177 {item.imageUrl && ( 178 <img src={item.imageUrl} alt="イメージ画像" /> 179 )} 180 {item.photoURL ? ( 181 <img src={ item.photoURL } alt="ユーザー画像" /> 182 ) : ( 183 <div>no image</div> 184 )} 185 </div> 186 </> 187 )} 188 </div> 189 ))} 190 </> 191 ); 192} 193 194export default Upload;

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

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

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

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

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

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問