❓발생한 이슈/고민
파이어베이스 회원가입 기능을 구현했는데
입력필드는
프로필 이미지, 이메일, 비밀번호, 비밀번호 확인, 닉네임 5가지이다.
그런데 프로필 이미지가 파이어베이스 스토리지에 저장은 되는데 이미지 속성이 png, jpg 등이 아니라
application/octet-stream 유형으로 나오는 것. 심지어 모두 9바이트 사이즈인 것을 보면 그냥 빈문서가 저장되는것 같아보였다.
문제가 되었던 코드
// 회원가입 함수 로직
const onSubmit = async (values: unknown) => {
const data = values as SignUpFormData;
try {
const userCredential = await createUserWithEmailAndPassword(auth, data.email, data.password);
const { user } = userCredential;
if (user) {
const userData = {
uid: user.uid,
email: data.email,
displayName: data.nickname,
photoURL: '',
};
if (data.profileImage.length > 0) {
const filePath = `profiles/${user.uid}/profile_picture`;
const imageRef = ref(storage, filePath);
const file = data.profileImage[0];
await uploadBytes(imageRef, file);
const downloadURL = await getDownloadURL(imageRef);
await updateProfile(user, {
displayName: data.nickname,
photoURL: downloadURL,
});
userData.photoURL = downloadURL; // 이미지 다운로드 URL을 데이터에 추가
}
// 파이어스토어 'users' 컬렉션에 데이터 추가
await addDoc(collection(db, 'users'), userData);
}
message.success('회원가입이 성공적으로 처리되었습니다');
setError(null);
navigate('/');
} catch (err) {
if (err instanceof FirebaseError) {
if (err.code === 'auth/email-already-in-use') {
setEmailError('이미 존재하는 이메일 주소입니다.');
} else {
setError(err.message);
}
} else {
setError('회원가입에 실패했습니다. 다시 시도해 주세요.');
}
}
};
// ..생략
// return의 tsx 부분
<Form.Item
label="프로필 이미지"
name="profileImage"
rules={[{ required: true, message: '이미지를 업로드해주세요.' }]}
>
<St.CustomFileInput type="file" id="profileImage" onChange={handleFileChange} />
</Form.Item>
💡해결과정
수정 전
if (data.profileImage.length > 0) {
const filePath = `profiles/${user.uid}/profile_picture`;
const imageRef = ref(storage, filePath);
const file = data.profileImage[0];
수정 후
if (selectedFile) {
const filePath = `profiles/${user.uid}/profile_picture`;
const imageRef = ref(storage, filePath);
const file = selectedFile;
// 이미지 onChange 함수 추가
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.files) {
setSelectedFile(e.target.files[0]);
}
};
// tsx 부분. 이미지 input에 적용
<St.CustomFileInput type="file" id="profileImage" onChange={handleFileChange} />
이미지가 제대로 저장되었다.
원인은.... 잘은 모르겠지만
프로필 이미지 핸들링 방식에 문제가 있었다고 생각한다.
원본 코드에서는 원본 코드에서는 data.profileImage를 사용하고 있다. (Form.Item 내에서 name 속성을 "profileImage"로 설정)
그렇게 하면 이미지 파일이 form 데이터의 일부로서 관리되고, 이 경우, form의 다른 요소들처럼 input 태그 변경 이벤트를 통해 파일 조작이 어려울 수 있을거라고 생각한다.
그래서 수정된 코드에서는 selectedFile이라는 상태 변수를 사용하여 이미지 파일을 저장하고 관리하도록 해서 이미지 파일을 input 태그의 변경 이벤트를 통해 자유롭게 조작할 수 있게 수정했다.
이 변경 사항으로 인해 이미지 관련 코드는 더 간결해지고 이미지 파일을 더 쉽게 관리할 수 있게 되었다.
따라서 이미지가 올바르게 저장 및 다운로드 되지 않는 문제가 해결된 것.
직접 이미지 상태를 관리하는 방식을 사용하면, 코드는 예기치 않은 동작이나 에러에 대해 더 강건(?)해진다.
'내일배움캠프 > Today I Learned' 카테고리의 다른 글
[TIL 2023.08.16] 최종 프로젝트 시작! (0) | 2023.08.16 |
---|---|
[TIL 2023.08.10] 리액트 타입스크립 댓글 수정 및 삭제 (0) | 2023.08.10 |
[TIL 2023.08.08] 심화 프로젝트 둘러보미 / 회원가입 만들기 (0) | 2023.08.08 |
[TIL 2023.08.07] 심화 프로젝트 둘러보미 (0) | 2023.08.07 |
[TIL 2023.08.04] Next.js 미니 영화 앱 만들기 (0) | 2023.08.04 |