Проверка двух разных коллекций пожарных хранилищ перед обновлением документа в каждой - PullRequest
0 голосов
/ 09 января 2020

Я использую Firestore, облачные функции и Admin SDK для создания блога / форума. Существует коллекция ForumPosts и коллекция ForumComments. Комментарии могут иметь вложенные комментарии, поэтому каждый комментарий в коллекции forumComments имеет идентификатор сообщения и идентификатор родительского комментария (комментарий непосредственно к сообщению (верхний уровень) имеет parentId = для postId).

Моя проблема в том, что когда комментарий публикуется, мне нужно сначала проверить, существует ли запись в блоге, затем, если родительский комментарий существует, и если оба условия выполняются, обновить счетчик комментариев для поста и счетчик комментариев для родительский комментарий ... затем добавьте новый комментарий в коллекцию forumComments. Очевидный ответ - предварительно выполнить каждый шаг, но для этого потребуется 4 чтения документа (4 получения) и 3 записи документа (2 обновления и 1 добавление) ... что сделает добавление комментария дорогой операцией.

Я не очень хорошо разбираюсь в обещаниях и активно пытаюсь узнать больше ... но я просто не могу понять эту функцию. Есть ли более эффективный способ сделать то, что я пытаюсь сделать? Любая помощь очень ценится!

Вот текущая структура моей функции:

index. js (содержит запрос http и маршруты)

app.post('/forumPost/:forumPostId/:parentId/comment', FBAuth, postOneForumComment);
exports.api = functions.https.onRequest(app);

forumPosts. js (содержит функцию postOneForumComment)

enter code hereexports.postOneForumComment = (req, res) => {
  if (req.body.body.trim() === '') return res.status(400).json({ comment: 'Must not be empty' });  //check if entry is empty

  const newComment = {
    body: req.body.body,
    createdAt: new Date().toISOString(),
    forumPostId: req.params.forumPostId,
    parentId: req.params.parentId,
    username: req.user.username,
    userImage: req.user.imageUrl,
    commentCount: 0,
    likeCount: 0
  };

db.doc(`/forumPosts/${req.params.forumPostId}`).get()
.then((postDoc) => {
  const promises = [];

    if (!postDoc.exists) {return res.status(404).json({ error: 'Post not found' });}    //check if the post exists

    db.doc(`/forumComments/${req.params.parentId}`).get()
      .then((comDoc) => {

          if (!comDoc.exists) {return res.status(404).json({ error: 'Comment not found' });}   //check if the comment exists

          const comProm = comDoc.ref.update({ commentCount: comDoc.data().commentCount + 1 });    //increment the comment count on the parent comment
          const postProm = postDoc.ref.update({ commentCount: postDoc.data().commentCount + 1 }); //increment the comment count on the post

          return promises.push(comProm, postProm);
      })
      .catch((err) => {
        console.log(err);
        return res.status(500).json({ error: 'Something went wrong during the comment retrival' });
      });

  return Promise.all(promises);
})
.then(() => {
  return db.collection('forumComments').add(newComment); //add the new comment
})
.then(() => {
  console.log("8");
  res.json(newComment);
})
.catch((err) => {
  console.log(err);
  res.status(500).json({ error: 'Something went wrong' });
 });
};

1 Ответ

0 голосов
/ 09 января 2020

Попробуйте просто добавить newComment на ваш веб-сервер. Вы можете обновлять количество комментариев асинхронно, используя облачную функцию. Это делает ваш веб-маршрут всего за 2 чтения и 1 запись.

В облачной функции вы можете просто предположить, что parentId и forumPostId уже существуют (то есть код, который разместил комментарий, выполнил необходимую проверку) и просто сделайте 2 записи, используя FieldValue.increment().

...