이미지 포함한 게시물 수정하기

Jian·2022년 10월 17일
0

Firebase

목록 보기
5/9

선수개념


  • Firestore update() 메서드 개념
  • Firebase rules

과정 요약


  1. product에서 데이터 받아와 DOM에 바인딩. (이때 imageURL은 imgURL변수에 따로 할당)
  2. 이미지 파일 변경 시, storage에 재업로드
  3. 제출 버튼 누르면, product 컬렉션 내 해당 도큐먼트 데이터 업데이트한다
    이때, 이미지 파일 변경여부 기준으로, 업로드 과정 나눈다
    • 변경 O : imgURL 변수 그대로 product 컬렉션에 저장
    • 변경 X : imgURLupdated 변수에 이미지 storage 업로드 시 새로 부여된 URL 할당

코드


0. DOM 생성 및 전역변수 선언, 할당

// 전역변수 목록
  var priceInput, imgURL, file, imgURLUpdated;
  var queryStr = new URLSearchParams(window.location.search);
  var productID = queryStr.get('id');
  var enableSubmit = false;

  getProductData();

  // 페이지 최초 진입 시 바인딩
  function getProductData() {
    db.collection('product')
      .doc(productID)
      .get()
      .then((result) => {
        console.log(result.data().title);

        priceInput = result.data().price;
        imgURL = result.data().image;
        // db서 가져온 내용 바인딩하기

        $('#img-trigger').attr('src', imgURL);

        $('#title').val(result.data().title);
        $('#content').val(result.data().content);
        $('#price').val(priceInput);
      });
  }

1. 제출 버튼 처리

  $('#upload').click(function (e) {
    e.stopPropagation();
    // 이미지 변경 o > db올리기, 아니면 기존 url
    if (file) {
      saveImgData();
      // saveDataInStore(imgURLUpdated);
      return;
    }
    saveDataInStore(imgURL);
  });

2. 이미지 데이터 저장

      function saveImgData() {
        file = document.querySelector('#image').files[0];
        storageRef = storage.ref();
        //파일 올려야 name이 definde됨
        loc = storageRef.child('image/' + file.name);
        uploading = loc.put(file);

        uploading.on(
          'state_changed',
          null,

          (error) => {
            console.error('실패사유는', error);
          },

          // 업로드 성공 시, 게시글 데이터를 product에 저장
          () => {
            uploading.snapshot.ref.getDownloadURL().then((url) => {
              console.log('[이미지 업로드 완료] 경로 : ', url);
              // 수정 후 이미지로 imageURL변경
              imgURLUpdated = url;
              console.log('업데이트후 url : ', imgURLUpdated);
              saveDataInStore(url);
            });
          }
        );
      }

3. string 타입 데이터 저장

function saveDataInStore(imgURLparams) {
        var data = {
          image: imgURLparams,
          title: $('#title').val(),
          content: $('#content').val(),
          price: Number($('#price').val()),
        };
        console.log(data);
        db.collection('product')
          .doc(productID)
          .update(data)
          .then((result) => {
            // 성공 후 저장된 결과가 담겨옴
            console.log('해당 게시글 DB 업로드 완료');
            // console.log(result.id);
            AnimateAlert();
          })
          .catch((err) => {
            // 실패 후 실행할 코드
            console.log(err);
            console.log('게시물 업로드 실패');
          });
      }

문제 해결 과정


1. 변경된 이미지 URL이 반영 안 되는 문제

이미지 수정 안 할 경우 / 수정할 경우로 나누어 처리함

1. 수정 안 할 경우
업로드 버튼 클릭 시 product 컬렉션에 업데이트할 img URL 데이터는
처음 DOM 바인딩할 때 사용한 데이터로 대체
2. 수정할 경우
이미지를 Firestore의 storage에 업로드 후,
결과로 받는 이미지 URL을 imgURL 변수에 재할당하려 함

But 반영안됨

string 데이터는 변경이 잘 반영되는데
imgURL은 재할당이 안된다.. (함수 scope 문제? 아님 덮어 썼으나 다시 기존 데이터로 덮어 씌워지거나? 아직 모르겠다...)

해결

업데이트 후 이미지URL(imgURLupdated) 변수 따로 생성 후, string 데이터 변경하는 함수를 1,2 경우가 공유하지 않고, 따로 작성해줌. 해당 함수에 파라미터로 이미지URL을 받는데 이것도 따로 설정해줌. 해결됨

2. Storage 권한 문제

디버깅 중 storage에 접근권한 없다고 뜸. 일반 사용자였으면 페이지 멈춘 줄 알았을 듯 함...
수정 페이지에서도 유저 로그인 여부 체크하여 로그인 안 했으면 페이지 진입 차단할 것

더 생각할 문제

storage에서 기존 이미지 데이터 삭제

profile
개발 블로그

0개의 댓글