UID 기반 workoutData 요청 - 1

SangYeon Min·2023년 11월 14일

PROJECT-RUF

목록 보기
5/6
post-thumbnail

운동 데이터 API 구현

MongoDB 스키마 작성

const setDetailSchema = new mongoose.Schema({
    set: Number,    // 세트
    weight: Number, // 무게
    number: Number, // 횟수
});

const summarizeSchema = new mongoose.Schema({
    RM: Number,         // RM
    accuracy: Number,   // 정밀도
    maxWeight: Number,  // 최대무게
    volume: Number,     // 볼륨
});

const workoutDataSchema = new mongoose.Schema({
    userToken: {
        type: String,
        required: true
    },
    workoutDate: {
        type: Date,
        default: Date.now,
        required: false,
    },
    workoutVideoUrl: Array,
    workoutProcUrl: Array,
    setDetail: [
        setDetailSchema
    ],
    summarize: summarizeSchema
});

userToken에는 기존 JWT 토큰이 사용되어도 되고 FB uid도 사용 가능하게 구현

// 테스트 데이터 셋
{
    "userToken": "test",
    "workoutDate": "2023-11-09T09:25:25.816+00:00",
    "workoutVideoUrl": [
        "test1.com",
        "test2.com",
        "test3.com"
    ],
    "workoutProcUrl": [
        "procTest1.com",
        "procTest2.com",
        "procTest3.com"
    ],
    "setDetail": [
        {
            "set": 1,
            "weight": 10,
            "number": 10
        },
        {
            "set": 2,
            "weight": 10,
            "number": 9
        },
        {
            "set": 3,
            "weight": 15,
            "number": 8
        }
    ],
    "summarize": {
        "RM": 5,
        "accuracy": 98,
        "maxWeight": 15,
        "volume": 100
    }
}

workout/postData 작성

router.post('/insertData', async (req, res) => {
    try {
        const woData = new workoutData(req.body);
        const woState = await woData.save();

        if (!woState) {
            const err = new Error("Internal Server Error");
            res.status(400).json({ success: false, err });
        }

        res.status(200).json({ success: true });
    } catch (err) {
        console.log(err);
        return res.status(500).json({
            sucess: false,
            message: err.message
        });
    }
});

테스트 데이터 셋을 body로 insertData에 요청하면 아래와 같은 오류 발생

TypeError: workoutData is not a constructor

workoutData modeld이 constructor로 인식되지 않아 발생하는 문제
아래와 같이 model을 그대로가 아니라 construct하여 export해 문제 해결

module.exports = {
    workoutData: mongoose.model('workoutData', workoutDataSchema)
};

workout/getData 작성

router.get('/getData', async (req, res) => {
    try {
        const startOfDay = new Date(req.query.startOfDay);
        const endOfDay = new Date(req.query.endOfDay);

        console.log(startOfDay);
        console.log(endOfDay);

        const woData = await workoutData.find({
            userToken: req.query.userToken,
            workoutDate: {
                $gte: startOfDay,
                $lte: endOfDay
            }
        });

        if (woData && woData.length > 0) {
            res.status(200).json({ woData });
        } else {
            res.status(404).json({
                message: "No workoutData found for the specified date range",
            });
        }
    } catch (error) {
        console.error(error);
        res.status(500).json({
            message: "Internal Server Error",
        });
    }
});

위와 같이 요청한 startOfDay와 endOfDay에 있는 모든 workoudData 반환

이때 $gte는 특정 값보다 크거나 같은 값을 매칭해주고
$lte는 특정 값보다 작거나 같은 값을 매칭해준다

또한 new Date(req.query.startOfDay)로 string을 Date로 변환할 수 있다
따라서 아래와 같이 find해주면 특정 값 사이에 있는 값을 불러올 수 있다

workoutDate: {
    $gte: startOfDay,
    $lte: endOfDay
}

아래는 요청 Param 정보이다

임의로 여러 날짜 데이터 셋을 입력하고 GET하면 아래와 같은 결과를 얻을 수 있다

{
    "woData": [
        {
            "_id": "654cd76e916408741845a98f",
            "userToken": "test",
            "workoutDate": "2023-11-09T09:25:25.816Z",
            "workoutVideoUrl": [
                "test1.com",
                "test2.com",
                "test3.com"
            ],
          ...
        },
        {
            "_id": "654cd7ed916408741845a995",
            "userToken": "test",
            "workoutDate": "2023-11-10T09:25:25.816Z",
        ...

UID 기반 API 요청 처리

uid를 middleware를 거쳐 token으로 처리되도록 요청

Firebase SDK 설정

npm으로 firebase 패키지를 설치하면 패키지를 찾을 수 없는 에러 발생
따라서 firebase-admin 패키지로 역할을 대신할 수 있도록 한다

npm install firebase-admin


아래와 같이 firebas-key.json을 추가하여준다

var firebase = require("firebase-admin");
...

// Firebase 설정
var serviceAccount = require("./firebase-key.json");

firebase.initializeApp({
	credential: firebase.credential.cert(serviceAccount)
});

console.log("Firebase SDK Connection Completed");

firebase register 테스트 수행

아래와 같이 firebase register route를 작성한다

router.post('/firebaseRegister', async (req, res) => {
	try {
		const result = await firebase.auth().createUser({
			email: req.body.email,
			password: req.body.password,
			displayName: req.body.username,
		});
		console.log(result);

		res.status(200).json({
			message: "Simple Register for testing Firebase auth",
		});
	} catch (error) {
		console.error(error);
		res.status(500).json({
			message: "Internal Server Error",
		});
	}
});

위 라우트로 아래 json body를 통해 요청하면 정상적으로 user가 생성된다

{
    "email": "test1234@test.com",
    "password": "test1234",
    "displayName": "test1234"
}

Firebase Token 처리 구체화

위와 같이 firebase token을 통해서 백엔드에서도 세션을 유지
데이터는 firebase UID와 함께 저장되고 UID를 통해 식별됨

따라서 데이터를 가져오거나 저장할 때 아래와 같이 fbToken을 식별하는 과정 필요

router.get('/getData', async (req, res) => {
    try {
      ...
      //firebase token을 검증하여 UID로 변환하는 과정 필요

        const woData = await workoutData.find({
            userToken: FIREBASE_UID,
            workoutDate: {
                $gte: startOfDay,
                $lte: endOfDay
            }
        });

0개의 댓글