-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.js
More file actions
217 lines (183 loc) · 6.43 KB
/
server.js
File metadata and controls
217 lines (183 loc) · 6.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
/* node.js */
// 라이브러리 불러오기
const express = require("express");
const path = require("path");
const app = express();
const http = require("http").createServer(app);
const schedule = require("node-schedule");
const admin = require("firebase-admin");
const serviceAccount = require("./firebase-admin.json");
const { getFirestore } = require("firebase-admin/firestore");
// node server.js
console.log("server is running...");
// Firebase Admin SDK 초기화
admin.initializeApp({
credential: admin.credential.cert(serviceAccount),
databaseURL: "https://gudok-87985.firebaseio.com",
});
// Firestore DB 불러오기
const db = getFirestore();
app.set("port", 3000);
app.listen(3000, function () {
console.log("listening on 3000");
});
// CORS 이슈 방지
app.use(express.json());
const cors = require("cors");
app.use(cors());
// 현재 날짜 구하는 함수
function getCurrentDate() {
const date = new Date();
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
return `${year}-${month}-${day}`;
}
// 초기 날짜 설정
let currentDate = getCurrentDate();
let currentMonth = currentDate.slice(5, 7);
// 자정을 계산하는 함수
function getNextMidnight() {
const now = new Date();
const nextMidnight = new Date(
now.getFullYear(),
now.getMonth(),
now.getDate() + 1, // 다음 날
0,
0,
0,
0 // 00:00:00.000
);
return nextMidnight;
}
// 자정에 날짜를 갱신하는 함수
function scheduleMidnightUpdate() {
const now = new Date();
const nextMidnight = getNextMidnight();
const timeUntilMidnight = nextMidnight - now;
setTimeout(() => {
currentDate = getCurrentDate();
currentMonth = currentDate.slice(5, 7);
// 자정 갱신 후 매일 24시간마다 갱신
setInterval(() => {
currentDate = getCurrentDate();
currentMonth = currentDate.slice(5, 7);
console.log(`Updated current date: ${currentDate}`);
}, 24 * 60 * 60 * 1000); // 24시간 후
}, timeUntilMidnight);
}
scheduleMidnightUpdate();
let addedHour, addedMin;
// FCM 보내기 함수
async function sendFCM() {
// user 컬렉션의 전체 데이터 읽기
const collectionRef = db.collection("user");
// 파이어스토어 데이터 업데이트 실시간 체크
collectionRef.onSnapshot((snapshot) => {
snapshot.docChanges().forEach((change) => {
if (change.type === "added") {
const newDocRef = change.doc.ref;
const subCollectionRef = newDocRef.collection("subscriptions");
subCollectionRef.onSnapshot((subSnapshot) => {
subSnapshot.docChanges().forEach((subChange) => {
const message = {
notification: {
title: `${subChange.doc.data().title}`,
body: `${subChange.doc.data().payDate}일에 ${subChange.doc
.data()
.price.toLocaleString("ko-KR")}원이 자동 결제됩니다.`,
},
// 푸시 알림 수신 대상 등 설정
token: subChange.doc.data().token
? subChange.doc.data().token
: "token",
};
// 저장된 구독 정보의 payDate 기반 사전알림 날짜 변수 설정
const payMonthStr = subChange.doc.data().payDate.slice(5, 7);
const payDateNum =
subChange.doc.data().payDate.slice(8) * 1 - 3 <= 0
? subChange.doc.data().payDate.slice(8) * 1 - 3 + 30
: subChange.doc.data().payDate.slice(8) * 1 - 3; // 3일 전에 전송
if (!subChange.doc.data().addDate) return;
addedHour = subChange.doc.data().addDate.slice(-8, -6) * 1;
addedMin = subChange.doc.data().addDate.slice(-5, -3) * 1;
// 이번 달에 해당될 경우에만 알림 전송
if (currentMonth === payMonthStr) {
schedule.scheduleJob(
`${addedMin + 1} ${addedHour} ${payDateNum} * *`,
function () {
admin
.messaging()
.send(message)
.then((response) => {
console.log("Successfully sent message:", response);
})
.catch((error) => {
console.error("Error sending message:", error);
});
}
);
}
});
});
}
});
});
}
sendFCM();
// 다음달 날짜를 구하는 함수
function getNextMonthDate(dateStr) {
let parts = dateStr.split("-");
let year = parts[0];
let month = parseInt(parts[1], 10);
let day = parts[2];
month += 1;
// 월이 13이 되면 연도에 1을 더하고 월을 1로 설정
if (month > 12) {
month = 1;
year = parseInt(year, 10) + 1;
}
// 월이 한 자리 숫자인 경우 두 자리로 변환
let newMonth = month < 10 ? "0" + month : month.toString();
return `${year}-${newMonth}-${day}`;
}
// payDate 갱신 함수
async function updatePayDate() {
const collectionRef = db.collection("user");
collectionRef.onSnapshot((snapshot) => {
snapshot.docChanges().forEach((change) => {
if (change.type === "added") {
const newDocRef = change.doc.ref;
const subCollectionRef = newDocRef.collection("subscriptions");
subCollectionRef.onSnapshot((subSnapshot) => {
subSnapshot.docChanges().forEach((subChange) => {
// payDate가 currentDate보다 작을 경우 payDate 갱신
if (currentDate > subChange.doc.data().payDate) {
let updatedMonthPayDate = getNextMonthDate(
subChange.doc.data().payDate
);
subChange.doc.ref
.update({ payDate: updatedMonthPayDate })
.then(() => {
// console.log(`updated to completed: ${updatedMonthPayDate}`);
})
.catch((error) => {
console.error(`Error updating document: `, error);
});
}
});
});
}
});
});
}
updatePayDate();
app.use(express.static(path.join(__dirname, "build")));
// 메인페이지 접속 시 build 폴더의 index.html 전송
app.get("/", (res, req) => {
req.sendFile(path.join(__dirname, "build", "index.html"));
});
app.get("*", (res, req) => {
req.sendFile(path.join(__dirname, "build", "index.html"));
});
module.exports = app;