firebase storage를 게시판 이미지 서버로 사용하고 있는데요. 게시판에 이미지를 업로드하고 글을 삭제하면 글 DB는 제거되지만 이미지는 이미지 서버에 그대로 남아있어 쓸데없는 용량만 차지하게 됩니다.
그래서 사용하지 않는 이미지를 찾아내 이미지 서버에서 삭제하는 코드를 작성해 보았습니다. Node.js 환경에서 진행합니다.
1. 전체 게시글 본문 불러오기
//async function
const allPost = await Post.find({}, { content : true });
게시판 DB는 MongoDB를 사용하고 있어 전체 게시글의 내용만 가져옵니다. content는 html 문자열로 저장되어 있습니다.
2. 스토리지 이미지 불러오기
import { initializeApp } from "firebase/app"
import { getStorage, ref, listAll, deleteObject } from "firebase/storage"
...
//파이어베이스 레퍼런스 생성 //스토리지 이미지 저장 경로
const listRef = ref(storage, 'profile_images');
const imgs = []; //전체 이미지 리스트
const useList = []; //사용중인 이미지 리스트
const { items } = await listAll(listRef);
items.forEach(i => imgs.push(i.name));
...
삭제할 이미지가 있는 스토리지 경로로 레퍼런스를 생성합니다. 그리고 전체 이미지 이름을 저장할 imgs 배열과 사용중인 이미지 배열을 만들어주고 listAll() 함수로 이미지를 받아와 이미지 이름만 배열에 넣어줍니다.
3. 사용중인 이미지 구분
//사용중인 이미지 구분
allPost.forEach(post =>{
items.forEach(img => {
const chk = post.content.includes(img.name);
if( chk === true ){
useList.push(img.name);
}else{
return false;
}
})
})
루프를 돌려 본문에 포함된 이미지들을 useList 배열에 넣어줘서 전체 이미지와 사용 중인 이미지를 제거해주면 사용하지 않는 이미지를 얻을 수 있습니다.
4. 사용하지 않는 이미지 구분
//전체 이미지 리스트 - 사용중인 리스트
useList.forEach(li => {
const idx = imgs.indexOf(li);
if(idx !== -1) imgs.splice(idx, 1);
})
전체 이미지 이름이 들어있는 imgs 배열에 사용 중인 이미지들을 splice() 메서드로 삭제해줍니다. 이제 imgs 배열에는 사용하지 않는 이미지 이름들만 남게 됩니다.
분명 3번과 4번은 알고리즘 계산을 잘하시는 분들이라면 코드를 짧게 줄일 수 있겠지만, 저는 이해하기 쉽게 조금 세분화해보았습니다. 나중에 리팩토링이 필요해 보입니다..
5. 사용하지 않는 이미지 삭제
import { initializeApp } from "firebase/app"
import { getStorage, ref, listAll, deleteObject } from "firebase/storage"
//사용하지 않는 이미지 삭제 처리
imgs.forEach(target => {
const desertRef = ref(storage, `/post_images/${target}`);
deleteObject(desertRef).then(() => {
console.log('삭제 성공');
}).catch((error) => {
console.log(error)
});
})
이미지 삭제는 deleteObject() 메서드를 사용하며 한 개씩 삭제해주어야 합니다. imgs 배열로 루프를 돌려 모두 삭제해줍니다.
6. 자동화
사용하지 않는 이미지를 자동화해 알아서 삭제 처리하게끔 만들어주면 편리할 거 같은데요. 이때 사용하기 좋은 스케쥴러 라이브러리가 있습니다. 예전 텔레그램으로 가상화폐 시세 알림봇을 만들 때 사용했던 라이브러리입니다.
> npm i --save node-cron
Cron Syntax
# ┌────────────── second (optional)
# │ ┌──────────── minute
# │ │ ┌────────── hour
# │ │ │ ┌──────── day of month
# │ │ │ │ ┌────── month
# │ │ │ │ │ ┌──── day of week
# │ │ │ │ │ │
# │ │ │ │ │ │
# * * * * * *
example
import cron from 'node-cron'
cron.schedule('*/10 * * * * *', ()=> {
console.log('10초 마다 실행');
});
//-------------------------------------------
cron.schedule('* */2 * * *', ()=> {
console.log('2시간 마다 실행');
});
//-------------------------------------------
cron.schedule('* 0 * * *', ()=> {
console.log('매일 자정 마다 실행');
}
대략 원하는 스케줄로 설정해 함수를 실행시켜주면 자동으로 이미지 삭제가 가능합니다.