这一行在/reviews/:uid 获得了单个(可能不存在)帖子:
const userPost = firestore.getDoc(firestore.doc(db, "reviews", uid));
您要做的是为集合 /reviews where docData.userId = uid 中的文档构建一个查询。
const reviewsColRef = firestore.collection(db, "reviews");
const userPostsQuery = firestore.query(reviewsColRef, firestore.where("userId", "==", uid));
const userPostsPromise = firestore.getDocs(userPostsQuery);
userPostsPromise
.then((querySnapshot) => {
const postsArray = querySnapshot.docs.map(docSnap => {
const docData = { id: docSnap.id, ...docSnap.data() };
delete docData.userId; // it's the same for every post, may as well omit it
delete docData.email; // same as above
return docData;
});
res.json({ posts: postsArray, count: postsArray.length });
})
.catch((err) => {
// don't send the full error object to the client,
// instead you should log the error and send the
// client as little information as possible
console.error(`Failed to get user posts for firebase:${uid}`, err);
res.status(500).json({ error: err.code || err.message }); // Don't forget to use an appropriate status code!
});
注意事项:
- 我建议使用解构来导入 Firestore 库。将其导入为
firestore 会抵消模块化 SDK 仅导入您需要的内容的好处。
import { getFirstore, query, collection, ... } from "firebase/firestore";
- 如果此代码在您控制的服务器上运行,请考虑改用 Firebase Admin SDK,因为这可以让您绕过安全规则并放宽速率限制。
import { getFirestore, query, collection, ... } from "firebase-admin/firestore";
- 附带说明,如果从 SDK 导入的名称与您想在其他地方使用的名称冲突,您可以重命名它。您可能会在同时使用 RTDB 和存储时看到这一点,因为它们都导出
ref:
import { getDatabase, ref: rtdbRef } from "firebase/database";
import { getStorage, ref: storageRef } from "firebase/storage";
const userDataRef = rtdbRef(getDatabase(), "users", uid, "data");
const imgStorageRef = storageRef(getStorage(), "path/to/image.png");
- 将电子邮件视为类似于电话号码的敏感数据。没有人喜欢垃圾邮件,限制从数据库中提取电子邮件的方法是一种很好的做法。除非您正在为公司网络开发内部工具,否则您应该尽可能隐藏用户的电子邮件。
- 电子邮件地址不应与评论一起存储。而是为每个用户保留一个包含文档的集合(例如,
/userProfile/:uid 的文档)并限制特权用户的访问。
- 考虑在用户不存在时添加
404 Not Found 错误。
- 考虑添加身份验证以限制对 API 的访问。