https://thumbnail-maker.web.app/

 

 

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
 # │ │ │ │ │ │
 # │ │ │ │ │ │
 # *   *   *   *   *   *

 

 

Crontab.guru - The cron schedule expression editor

 

crontab.guru

 

example

import cron from 'node-cron'

cron.schedule('*/10 * * * * *', ()=> {
	console.log('10초 마다 실행');
});

//-------------------------------------------

cron.schedule('* */2 * * *', ()=> {
	console.log('2시간 마다 실행');
});

//-------------------------------------------

cron.schedule('* 0 * * *', ()=> {
	console.log('매일 자정 마다 실행');
}

 

대략 원하는 스케줄로 설정해 함수를 실행시켜주면 자동으로 이미지 삭제가 가능합니다.