昔実装したReact + Firestoreの登録・削除機能を久しぶりに実装してみたところ登録は以前のようにできたのですが、削除が一向にされないという不具合が発生しました。
その原因を追求したところどうやらuseCollectionData
で呼び出し,
console.log(list.docId);
でdocId
を出そうしたところ何故かundefied
になってしまいます。
docId
がundefied
になるがゆえに
<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;

あなたの回答
tips
プレビュー