이전에 처리를 끝마치지 못했던 이미지 관련 처리를 fireBase의 Storage를 사용하여 해결했다
Realtime, Firestore 모두 텍스트 데이터만 취급하기 때문에 이미지, 동영상 등의 파일은 Storage를 써야 하는 것을 배웠다.
firebase 콘솔로 가서 내 프로젝트에 Storage를 생성해준 후, 내 js 파일에 초기화했다.
// 이미지 저장용 스토리지 초기화
const Imgstorage = firebase.storage();
Storage에 이미지를 올리고, Storage에 있는 이미지의 URL을 포함한 member데이터를 realtime DB에 넣어 데이터를 관리할 것이다.
let imgUrl = ""; // 이미지 URL을 저장할 전역 변수
// 이벤트 리스너 추가
document.getElementById('memberform').addEventListener('submit', memberSubmit);
// 멤버 저장 함수
function memberSubmit(e){
e.preventDefault();
var name = getElementVal('name');
var intro = getElementVal('intro');
// 이미지 업로드 후 URL이 있을 경우에만 멤버 저장
if (imgUrl) {
saveMember(name, intro, imgUrl);
} else {
console.log('이미지 업로드 후에 제출하세요.');
}
}
// db push 함수
const saveMember = (name, intro, imgUrl) => {
var newMember = memberformDB.push();
newMember.set({
name: name,
intro: intro,
imgUrl: imgUrl
});
}
일단 URL을 받을 변수 하나를 만들어줬고, DB에 member가 들어갈 수 있도록 했다.
document.getElementById("imgSmt").addEventListener('click',submitImg);
function submitImg(e) {
e.preventDefault();
// 파일 선택 확인
var file = document.querySelector('#imgInput').files[0]; //파일 가져오기
if (file) {
// 스토어 위치 가져옴
var storageRef = Imgstorage.ref();
var saveLocation = storageRef.child('image/' + file.name); // 파일명으로 경로 설정
// 이미지 저장 함수 호출
SaveImgfn(file, saveLocation);
} else {
console.log('파일을 선택해 주세요.'); // 파일이 선택되지 않은 경우
}
}
이미지를 Storage에 넣을 수 있는 submitImg 함수를 구현했다.
일단 사용자가 올릴 파일을 가져오고, 파일이 있다면 저장할 경로를 설정해준다. 그리고 이미지 저장 함수를 호출한다.
const SaveImgfn = (file, saveLocation) => {
saveLocation.put(file).then((snapshot) => {
console.log('파일 업로드 성공:', file.name);
return snapshot.ref.getDownloadURL();
}).then((url) => {
imgUrl = url; // imgUrl에 저장
console.log('이미지 다운로드 URL:', imgUrl)})
.catch((error) => {
console.error('파일 업로드 실패:', error);
});
};
.put()함수를 이용해서 파일을 경로에 맞춰 저장해준다. 또한 파일 업로드가 잘 되었다면, snapshot.ref.getDownloadURL()을 호출하여 파일의 다운로드 URL을 return 하고 받아온다.
아까 설정한 경로에 맞춰 잘 저장이 된 것을 확인할 수 있다!
콘솔로 들어간 member 오브젝트를 찍어보니 이미지도 URL로 잘 들어갔다!
memberformDB.on('child_added',(snapshot)=>{
const memberObj = snapshot.val();
const memberId = snapshot.key; // 데이터의 고유 키값 가져오기
console.log(memberObj);
const membercardWrapper = document.getElementById('membercardWrapper');
const name = memberObj.name;
const intro = memberObj.intro;
const imgUrl = memberObj.imgUrl;
const memberDiv = document.createElement('div');
memberDiv.classList.add('memCard');
const nameDiv=document.createElement("div");
const introDiv=document.createElement("div");
const imgDiv=document.createElement("img");
nameDiv.innerText = name;
introDiv.innerText =intro;
imgDiv.src = imgUrl;
//삭제 버튼 이벤트리스너
deleteBtn.addEventListener('click', () => {
// Firebase에서 해당 데이터 삭제
memberformDB.child(memberId).remove()
.then(() => {
console.log("데이터가 삭제되었습니다.");
memberDiv.remove(); // UI에서 해당 카드 제거
})
.catch((error) => {
console.error("데이터 삭제 실패:", error);
});
});
memberDiv.appendChild(nameDiv);
memberDiv.appendChild(introDiv);
memberDiv.appendChild(imgDiv);
memberDiv.appendChild(deleteBtn);
membercardWrapper.appendChild(memberDiv);
})
.on('child_added')로 데이터가 추가될 때마다 데이터를 읽어오고, UI에 추가해주는 코드도 작성했다. 삭제를 위해 snapshot.key로 key값을 받고, .child(해당 키값)로 특정 위치의 하위 노드에 접근해준다. .remove()를 사용해 위치에 있는 데이터를 삭제하도록 했다. 수정을 위해선 .set()또는 .update()을 사용하면 데이터 수정도 구현할 수 있다!
이렇게 firebase로 이미지 포함한 데이터 CRUD를 구현했다. 뿌듯하네요.