MongoDB에서 저장된 데이터가 조회되지 않는 문제 해결 과정

henry·2025년 3월 11일

📌 문제 상황

  • 장바구니 추가 API (POST /cart/)는 정상 작동하고 MongoDB에 데이터가 저장됨.
  • 장바구니 조회 API (GET /cart/)를 호출하면 데이터가 조회되지 않음.
  • Cart.findOne({ userId }) DB조회가 null을 반환하여 조회 실패.

🧐 문제 원인 분석

1️⃣ MongoDB에 저장된 Cart 데이터 확인

  • findOne({})으로 조건 없이 조회하면 데이터가 존재함.
  • 그러나 findOne({ userId })로 조회하면 null이 반환됨.

MongoDB에서 실제 저장된 데이터

{
    "_id": "67d050d9597eb94a2db084cc",
    "items": [
        {
            "productId": "67cfb542ec43354f94c1a9c7",
            "size": "xxl",
            "qty": 1,
            "_id": "67d050d9597eb94a2db084cd"
        }
    ],
    "isDeleted": false,
    "__v": 0
}

🚨 문제 발견: userId 필드가 없음!


2️⃣ 장바구니 추가(POST /cart/) 시 userId 저장되지 않음

🔍 디버깅 코드 추가 (cartController.addItemToCart)

cartController.addItemToCart = async (req, res) => {
try {
console.log("요청 Body:", req.body);
console.log("req.userId:", req.userId); // 인증된 사용자 ID 확인

  const data = { ...req.body, userId: req.userId };  // userId 추가

  const cart = await cartService.addItemToCart(data);

  return res.status(StatusCodes.OK).json({
     status: "success",
     data: cart,
     cartItemCount: cart.items.reduce((acc, item) => acc + item.qty, 0),
  });

} catch (error) {
console.error("장바구니 추가 실패:", error);
res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
status: "fail",
error: error.message,
});
}
};

요청 Body 로그 결과

요청 Body: { productId: '67cfb542ec43354f94c1a9c7', size: 'xxl', qty: 1 }
req.userId: undefined

🚨 userId가 undefined이므로 Cart 저장 시 userId 필드가 빠짐.


🚀 해결 방법

✅ 1. userId가 req.body에 없으므로 추가

수정된 cartController.addItemToCart

cartController.addItemToCart = async (req, res) => {
   try {
      const data = { ...req.body, userId: req.userId };  // userId 추가

      const cart = await cartService.addItemToCart(data);

      return res.status(StatusCodes.OK).json({
         status: "success",
         data: cart,
         cartItemCount: cart.items.reduce((acc, item) => acc + item.qty, 0),
      });
   } catch (error) {
      res.status(StatusCodes.INTERNAL_SERVER_ERROR).json({
         status: "fail",
         error: error.message,
      });
   }
};

✅ 2. req.userId가 undefined인 원인 점검

  • req.userId는 authController.authenticate에서 설정됨.
    authController.authenticate에서 로그 추가
jwt.verify(token, JWT_SECRET_KEY, (error, payload) => {
   if (error) throw new Error('토큰값이 유효하지 않습니다.');
   console.log('Decoded JWT payload:', payload);
   req.userId = payload._id;
   console.log("req.userId in authenticate : ", req.userId);  
   next();
});

로그 결과

req.userId in authenticate : 67d002f3ca23fd956856a565
  • Postman에서 API 요청 시 Authorization 헤더를 추가해야 req.userId가 설정됨.

Authorization: Bearer <토큰값>

🚨 해결: POST /cart/ 요청 시 Authorization 헤더를 포함하여 userId 전달.


✅ 3. userId 필드를 ObjectId로 저장하도록 모델 수정

  • 현재 userId가 String으로 저장되고 있어 조회 시 일치하지 않음.

cart.model.js 수정

const CartSchema = Schema(
   {
      userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
      items: [
         {
            productId: { type: mongoose.Schema.Types.ObjectId, ref: 'Product' },
            size: { type: String, required: true },
            qty: { type: Number, default: 1 },
         },
      ],
      isDeleted: { type: Boolean, default: false },
   },
   { timestamps: true }
);

✅ 4. userId를 ObjectId로 변환하여 조회

const getCartByUserId = async (userId) => {
   try {
      const objectId = new mongoose.Types.ObjectId(userId); // userId 변환
      const cart = await Cart.findOne({ userId: objectId }).populate({
         path: 'items',
         populate: {
            path: 'productId',
            model: 'Product',
         },
      });

      if (!cart) {
         console.log('장바구니 데이터 없음:', userId);
         return null;
      }

      return cart;
   } catch (error) {
      throw new Error('장바구니 조회 실패: ' + error.message);
   }
};

🚨 이제 GET /cart/에서 userId가 ObjectId로 조회되어 정상 작동!


조회 결과

GET /api/cart/

{
    "status": "success",
    "data": {
        "_id": "67d05488f0fe19c97c4d4949",
        "userId": "67d002f3ca23fd956856a565",
        "items": [
            {
                "productId": {
                    "_id": "67cfb542ec43354f94c1a9c7",
                    "sku": "425242LY54",
                    "name": "가먼트 다잉 바이크 그래픽 티셔츠 - 애쉬",
                    "image": "https://res.cloudinary.com/dov0crjjv/image/upload/v1741665581/easgycyend2uda7wgb4q.jpg",
                    "category": [
                        "top",
                        "티셔츠",
                        "상의"
                    ],
                    "description": "가먼트 다잉 기법으로 제작돼 색감이 독특한 반소매 티셔츠입니다. 오버핏 스타일로 편안한 착용감을 선사하며, 16수 싱글 소재로 내구성이 튼튼합니다. 포인트로 더해진 바이크 그래픽 프린트가 시선을 끕니다. 데일리하게 활용하기 제격인 아이템입니다.",
                    "price": 39900,
                    "stock": {
                        "m": 50,
                        "l": 50,
                        "xl": 50,
                        "xxl": 50
                    },
                    "status": "active",
                    "isDeleted": false,
                    "__v": 0
                },
                "size": "xxl",
                "qty": 1,
                "_id": "67d05488f0fe19c97c4d494a"
            }
        ],
        "isDeleted": false,
        "createdAt": "2025-03-11T15:19:36.247Z",
        "updatedAt": "2025-03-11T15:19:36.247Z",
        "__v": 0
    }
}

0개의 댓글