완성작
.gif?table=block&id=09bb719f-a770-45c3-b6e2-ed7768e9d0df&cache=v2)
제작 과정
이미지 업로드
버튼을 클릭하고 이미지를 첨부하면 firebase storage에 해당 파일이 저장됨.

- 다른 HTML 페이지 이동시 돔 객체 잔류 현상 → transition 때문일 가능성 있음. CSS에 불필요한 애니메이션이 들어가지 않는지 확인하기.
- input 태그를 사용하여 file을 첨부할 수 있게 만듦. 이때 input 태그를 커스터마이즈할 수 없기 때문에 label 태그의 자식으로 input을 넣어 label 태그를 꾸며줌.
- createObjectURL() - 주어진 객체를 가리키는 URL을 DOMString으로 반환함.
이미지 삭제
delete 버튼 클릭 시 기본 이미지 주소 전달.


- firebase에서 전체 파일을 삭제하는 기능이 없으므로 forEach로 반복해서 모든 파일을 지워줌.
- file을 빈 오브젝트 파일로 설정한 후 이미지 변화없이 change를 누를 경우 빈 값이 담기는 문제 → file을 null로 지정하고 이미지 업로드 시 null이면 반환.
완료 버튼
적용했을 때 firebase로 이미지를 전송할 수 있도록 함.

uploadProfile과 updateProfile 함수를 만들어 uploadProfile에서는 유저의 이메일 안에 Date.now()를 사용하여 업로드 시간을 기준으로 업로드하게 만듦. updateProfile는 list에서 가장 마지막에 위치한 이름을 프로필로 가져오도록 함.
async function uploadFile(file) { try { const user = auth.currentUser; const ref = storage.ref(`users profile/${user.email}/${Date.now()}`); await ref.put(file); updateProfile(user); } catch (error) { console.log(error); } }
- addEventListener : change - 사용자의 변경이 일어나는<input>, <select>, <textarea>에 사용됨.
- put() - firebase에서 자바스크립트 File 및 Blob API를 통해 파일을 가져와서 Cloud Storage에 업로드함.
- Date.now() - UTC 기준으로 1970년 1월 1일 0시 0분 0초부터 현재까지 경과된 밀리 초를 반환함.
- firebase put api를 호출하는 과정이 네트워크 통신을 필요해서 비동기 방식 사용.
- firebase json 파일을 별도의 config로 만들어 하나의 파일로 관리하는 것이 좋음.
async function updateProfile(user) { const rootRef = firebase.storage().ref(); const userRef = rootRef.child(`users profile/${user.email}`); const res = await userRef.listAll(); const { items } = res; if (items.length === 0) { return; } const fileName = items[items.length - 1].name; const fileRef = userRef.child(fileName); const imgUrl = await fileRef.getDownloadURL(); profileImg.src = imgUrl; }
처음에 파일 이름으로 저장을 하니 알파벳 순으로 나열이 되어 가장 최근 업로드 파일을 파악하기 어려웠음 → include를 사용하여 업로드한 파일 이름과 맞는 파일을 업로드 하기로 함. 하지만 다음 접속시 저장이 어렵다는 단점이 있음 → 업로드 날짜로 파일 이름을 생성하게 하자!
- getDownloadURL() - firebase로부터 파일의 다운로드 URL을 가져올 수 있음.
취소 버튼
머물렀던 html 페이지로 되돌아가기.

- history.back() - 브라우저가 세션 기록의 바로 뒤 페이지로 이동하도록 지시함.
firebase보다 app.js가 더 빨리 로드되는 현상 → appendChild를 이용해 동적으로 스크립트를 불러오게 함. 또는 index.js를 만들어 로드가 지연되는 부분을 하나의 script로 만듦.
네비게이션 바 수정
프로필을 변경했을 때, 네비게이션 프로필 사진이 변경되어야 함.

QA
- 권한 설정 - 로그인한 유저만 작성 및 수정 가능.

- 업로드 용량 제한
if (file.size > 2097152) { editAlert.style.color = '#e55e70'; return; }
마치며
프로필 수정 페이지는 만만하게 보고 시작했다가 어려워서 당황했다. firebase와 연동되는 것도 있고, 로컬로부터 파일을 받아 작업하는 것도 쉽지 않았다. 특히, 내 코드 패턴에 대해 생각해보는 계기가 되었다. 코드를 작성하다 보니 파일 간의 의존성이 생기고 상태 관리가 어려워졌다.
그래서 component pattern이라는 걸 알아봐야겠단 생각이 들었다. component pattern이란 컴포넌트 간의 메시지를 전달하며 자식과 같은 관계를 가지는거라던데 다음에 작은 프로젝트로 실습해볼 예정이다.
🤔 의존성과 상태관리 공부하기