Skip to content

Commit

Permalink
Merge pull request #110 from MurakawaTakuya/faet/108-api-firestore-da…
Browse files Browse the repository at this point in the history
…ta-type

APIのレスポンスとFirestoreのデータをtypesに合わせる
  • Loading branch information
MurakawaTakuya authored Dec 12, 2024
2 parents 0760e16 + ce5e997 commit 72c88d0
Show file tree
Hide file tree
Showing 16 changed files with 125 additions and 68 deletions.
28 changes: 18 additions & 10 deletions functions/src/routers/goalRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,22 @@ const db = admin.firestore();
router.get("/", async (req: Request, res: Response) => {
try {
const goalSnapshot = await db.collection("goal").get();

if (goalSnapshot.empty) {
return res.status(404).json({ message: "No goals found" });
}

const goals = goalSnapshot.docs.map((doc) => {
const goalData: Goal[] = goalSnapshot.docs.map((doc) => {
const data = doc.data();
return {
id: doc.id,
...data,
goalId: doc.id,
deadline: new Date(data.deadline._seconds * 1000),
userId: data.userId,
text: data.text,
};
});

return res.json(goals);
return res.json(goalData);
} catch (error) {
return res.status(500).json({ message: "Error fetching goals" });
}
Expand All @@ -46,12 +48,13 @@ router.get("/:userId", async (req: Request, res: Response) => {
return res.status(404).json({ message: "No goals found for this user" });
}

const goals = goalSnapshot.docs.map((doc) => {
const goals: Goal[] = goalSnapshot.docs.map((doc) => {
const data = doc.data();
return {
id: doc.id,
...data,
goalId: doc.id,
userId: data.userId,
deadline: new Date(data.deadline._seconds * 1000),
text: data.text,
};
});

Expand Down Expand Up @@ -113,12 +116,17 @@ router.put("/:goalId", async (req: Request, res: Response) => {
const updateData: Partial<Omit<Goal, "deadline">> & {
deadline?: admin.firestore.Timestamp;
} = {};
if (userId) updateData.userId = userId;
if (deadline)
if (userId) {
updateData.userId = userId;
}
if (deadline) {
updateData.deadline = admin.firestore.Timestamp.fromDate(
new Date(deadline)
);
if (text) updateData.text = text;
}
if (text) {
updateData.text = text;
}

try {
await db.collection("goal").doc(goalId).update(updateData);
Expand Down
43 changes: 29 additions & 14 deletions functions/src/routers/postRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,25 @@ const db = admin.firestore();
router.get("/", async (req: Request, res: Response) => {
try {
const postSnapshot = await db.collection("post").get();

if (postSnapshot.empty) {
return res.status(404).json({ message: "No posts found" });
}

const posts = postSnapshot.docs.map((doc) => {
const postData: Post[] = postSnapshot.docs.map((doc) => {
const data = doc.data();
return {
id: doc.id,
...data,
postId: doc.id,
userId: data.userId,
storedId: data.storedId,
text: data.text,
goalId: data.goalId,
submittedAt: new Date(data.submittedAt._seconds * 1000),
};
});

return res.json(posts);
return res.json(postData);
} catch (error) {
console.log(error);
return res.status(500).json({ message: "Error fetching posts" });
}
});
Expand All @@ -49,8 +52,11 @@ router.get("/:userId", async (req: Request, res: Response) => {
const posts = postSnapshot.docs.map((doc) => {
const data = doc.data();
return {
id: doc.id,
...data,
postId: doc.id,
userId: data.userId,
storedId: data.storedId,
text: data.text,
goalId: data.goalId,
submittedAt: new Date(data.submittedAt._seconds * 1000),
};
});
Expand Down Expand Up @@ -82,6 +88,7 @@ router.post("/", async (req: Request, res: Response) => {
message: "userId, storedId, text, goalId, and submittedAt are required",
});
}

if (!text) {
text = "";
}
Expand Down Expand Up @@ -110,16 +117,24 @@ router.put("/:postId", async (req: Request, res: Response) => {
const { userId, storedId, text, goalId }: Partial<Post> = req.body;

if (!userId && !storedId && !text && !goalId) {
return res
.status(400)
.json({ message: "At least one field is required to update" });
return res.status(400).json({
message: "At least one of userId, storedId, text, or goalId is required",
});
}

const updateData: Partial<Post> = {};
if (userId) updateData.userId = userId;
if (storedId) updateData.storedId = storedId;
if (text) updateData.text = text;
if (goalId) updateData.goalId = goalId;
if (userId) {
updateData.userId = userId;
}
if (storedId) {
updateData.storedId = storedId;
}
if (text) {
updateData.text = text;
}
if (goalId) {
updateData.goalId = goalId;
}

try {
await db.collection("post").doc(postId).update(updateData);
Expand Down
1 change: 1 addition & 0 deletions functions/src/routers/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export interface User {
name: string;
streak: number;
fcmToken?: string;
}

export interface Goal {
Expand Down
76 changes: 53 additions & 23 deletions functions/src/routers/userRouter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@ router.get("/", async (req: Request, res: Response) => {
return res.status(404).json({ message: "No users found" });
}

const userData = userSnapshot.docs.map((doc) => ({
uid: doc.id,
...doc.data(),
}));
const userData: User[] = userSnapshot.docs.map((doc) => {
const data = doc.data();
return {
userId: doc.id,
name: data.name,
streak: data.streak,
};
});

return res.json(userData);
} catch (error) {
Expand All @@ -35,10 +39,20 @@ router.get("/id/:userId", async (req: Request, res: Response) => {

try {
const userDoc = await getUserFromId(userId);

if (!userDoc.exists) {
return res.status(404).json({ message: "User not found" });
}
return res.json({ uid: userDoc.id, ...userDoc.data() });

const data = userDoc.data();

const userData: User & { userId: string } = {
userId: userDoc.id,
name: data?.name || "",
streak: data?.streak || 0,
};

return res.json(userData);
} catch (error) {
return res.status(500).json({ message: "Error fetching user data" });
}
Expand All @@ -54,44 +68,53 @@ router.get("/name/:userName", async (req: Request, res: Response) => {

try {
const userSnapshot = await getUserFromName(userName);

if (userSnapshot.empty) {
return res.status(404).json({ message: "User not found" });
}

const userData = userSnapshot.docs.map((doc) => ({
uid: doc.id,
...doc.data(),
}));
const userData: User[] = userSnapshot.docs.map((doc) => {
const data = doc.data();
return {
userId: doc.id,
name: data.name,
streak: data.streak,
};
});

return res.json(userData[0]);
return res.json(userData);
} catch (error) {
return res.status(500).json({ message: "Error fetching user data" });
}
});

// POST: 新しいユーザーを登録
router.post("/", async (req: Request, res: Response) => {
let userId: string;
let name: User["name"];
let uid: string;
let streak: User["streak"];
let fcmToken: User["fcmToken"];

try {
({ name, uid, streak = 0 } = req.body);
({ name, userId, streak = 0, fcmToken = "" } = req.body);
} catch (error) {
return res.status(400).json({ message: "Invalid request body" });
}

if (!name || !uid) {
return res.status(400).json({ message: "name and uid are required" });
if (!name || !userId) {
return res.status(400).json({ message: "name and userId are required" });
}

try {
await db.collection("user").doc(uid).set({
await db.collection("user").doc(userId).set({
name: name,
streak: streak,
fcmToken: fcmToken,
});

return res.status(201).json({ message: "User created successfully", uid });
return res
.status(201)
.json({ message: "User created successfully", userId });
} catch (error) {
return res.status(500).json({ message: "Error creating user" });
}
Expand All @@ -100,17 +123,24 @@ router.post("/", async (req: Request, res: Response) => {
// PUT: ユーザー情報を更新
router.put("/:userId", async (req: Request, res: Response) => {
const userId = req.params.userId;
const { name, streak }: Partial<User> = req.body;
const { name, streak, fcmToken }: Partial<User> = req.body;

if (!name && streak === undefined) {
return res
.status(400)
.json({ message: "At least one of name or streak is required" });
if (!name && !streak && !fcmToken) {
return res.status(400).json({
message: "At least one of name, streak, or fcmToken is required",
});
}

const updateData: Partial<User> = {};
if (name) updateData.name = name;
if (streak !== undefined) updateData.streak = streak;
if (!name) {
updateData.name = name;
}
if (!streak) {
updateData.streak = streak;
}
if (fcmToken !== undefined) {
updateData.fcmToken = fcmToken;
}

try {
await db.collection("user").doc(userId).update(updateData);
Expand Down
5 changes: 4 additions & 1 deletion functions/src/tasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,11 @@ const getUserFcmToken = async (userId: string) => {
if (!userData) {
throw new Error(`No user data found for userId:, ${userId}`);
}
if (!userData.fcmToken) {
if (!userData.fcmToke) {
throw new Error(`No FCM token found for userId:, ${userId}`);
}
if (userData.fcmToken === "") {
throw new Error(`FCM token is not stored for userId:, ${userId}`);
}
return userData.fcmToken;
};
2 changes: 1 addition & 1 deletion src/Components/GoalModal/GoalModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default function GoalModal() {
event.preventDefault();

const postData: Goal = {
userId: user?.uid as string,
userId: user?.userId as string,
text: text,
deadline: new Date(dueDate),
};
Expand Down
2 changes: 1 addition & 1 deletion src/Components/NameUpdate/NameUpdate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default function NameUpdate({
const handleNameUpdate = async (event: React.FormEvent) => {
event.preventDefault();

const response = await fetch(`${functionsEndpoint}/user/${user?.uid}`, {
const response = await fetch(`${functionsEndpoint}/user/${user?.userId}`, {
method: "PUT",
headers: {
"X-Firebase-AppCheck": appCheckToken,
Expand Down
2 changes: 1 addition & 1 deletion src/Components/PostModal/PostModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export default function PostModal({ goalId }: { goalId: string }) {
(errorMsg) => setError(errorMsg),
async (url) => {
const postData: Post = {
userId: user?.uid as string,
userId: user?.userId as string,
storedId: url,
text: text,
goalId: goalId,
Expand Down
2 changes: 1 addition & 1 deletion src/Components/Progress/Progress.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ const pendingStep = (result: GoalWithId, userName: string, user: UserData) => {
resultType="pending"
/>
{/* 自分の作成した目標の場合のみ投稿可能にする */}
{result.userId === user?.uid && <PostModal goalId={result.goalId} />}
{result.userId === user?.userId && <PostModal goalId={result.goalId} />}
</Step>
</StepperBlock>
);
Expand Down
4 changes: 2 additions & 2 deletions src/app/mycontent/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ export default function MyContent() {
</div>

{value == "pending" ? (
<DashBoard userId={user?.uid} success={false} failed={false} />
<DashBoard userId={user?.userId} success={false} failed={false} />
) : (
<DashBoard userId={user?.uid} pending={false} />
<DashBoard userId={user?.userId} pending={false} />
)}
</>
);
Expand Down
2 changes: 1 addition & 1 deletion src/types/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export interface UserData {
uid: string;
userId: string;
name: string;
streak: number;
loginType: LoginType;
Expand Down
8 changes: 4 additions & 4 deletions src/utils/API/createUser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@ import { appCheckToken, functionsEndpoint } from "@/app/firebase";

/**
* Cloud FunctionsのAPIを呼び出して、ユーザー情報をFirestoreに登録する
* Authenticationのuidと/userのdocument IDは同じにする
* AuthenticationのuserIdと/userのdocument IDは同じにする
*
* @param {string} name
* @param {string} uid
* @param {string} userId
*/
export const createUser = async (name: string, uid: string) => {
export const createUser = async (name: string, userId: string) => {
const response = await fetch(`${functionsEndpoint}/user/`, {
method: "POST",
headers: {
"X-Firebase-AppCheck": appCheckToken,
"Content-Type": "application/json",
},
body: JSON.stringify({ uid, name }),
body: JSON.stringify({ userId, name }),
});

if (!response.ok) {
Expand Down
Loading

0 comments on commit 72c88d0

Please sign in to comment.