Firebase Firestore: как запросить соответствующие документы, а затем обновить каждый из них - PullRequest
0 голосов
/ 14 апреля 2020

Я занимаюсь разработкой веб-приложения для Firebase / firestore, в котором пользователи могут входить и писать свои собственные сообщения. Данные хранятся следующим образом:

-Пользовательская информация хранится как под коллекцией ('user'). Do c ('uid').

-Информация о публикациях написанное пользователем хранится в коллекции ('post'). do c ('postid'), а do c имеет поля 'userinfo' и 'uid'. Поле 'userinfo' содержит точную копию того, что хранится в 'uid' do c, просто в формате объекта.

Вот операции, которые я хочу сделать:

  1. Когда пользователь изменяет данные, эти изменения отражаются в документе.

  2. Найдите все сообщения, которые пользователь написал на основе данных 'uid', а затем обновите userinfo в этих данных.

Последняя часть сложна для меня. Документация Firebase охватывает ситуации, когда ссылки в значительной степени уста- навливаются c, т.е. вы знаете точный путь для записи / обновления. То, что я пытаюсь сделать, это найти набор документов, который не обязательно должен быть c, а затем обновить каждый из них.

Вот код, который я написал для этой работы. Первая часть работает без проблем. Конечно, вторая часть не работает. :) Каков будет код для выполнения второй части?

 const update = () => {
             //This part is for updating user information. This works without any problem.
             firebase.firestore().collection('user').doc(user.uid).update({
                 username: username1,
                 nickname: nickname1,
                 intro: intro1 
             })
            .then(()=>{
             //This part is for updating all of the document that the user has written based on 'uid' value. This doesn't work. 
             //Below code is probably way off, but it shows where I am going and what I am trying to do.
             firebase.firestore().collection('post').where('uid','==',user.uid).get()
                 .then((querysnapshot)=>{
                     querysnapshot.forEach((doc)=>{
                         let ref=firebase.firestore().collection('post').doc(doc.id);
                             ref.update({
                                 userinfo: {nickname:nickname1,username:username1,intro:intro1}
                             })
                        })
                     })
                }).then(()=>{
                    alert("Successfully updated!");
                    window.location.href='/'+username1;
                }).catch((error)=>{
                    alert("Error!"); 
                })
}

Заранее большое спасибо!

1 Ответ

1 голос
/ 14 апреля 2020

В чём ошибка при запуске этого кода? Кажется, на правильном пути для меня.

Но, несмотря на это, вот несколько советов по поводу такого обновления:

  • Не делайте вторую часть на стороне клиента, делайте это на на стороне сервера с триггером Firestore (в вашем случае создайте триггер onUpdate в коллекции пользователей): https://firebase.google.com/docs/functions/firestore-events.

    • Проблема на стороне клиента заключается в том, что если пользователь закрывает страницу / браузер или сайт переходит в автономный режим в середине обновления, у вас будут противоречивые данные.
  • Вам не нужно пересоздавать DocumentReference после получения результата запроса, возвращенные документы уже имеют .ref, который можно напрямую вызывать .ref.update ().

РЕДАКТИРОВАТЬ : Если вы хотите сохранить свой исходный код (обновление на стороне клиента), проблема с навигацией, возникающей до завершения всех обновлений, заключается в том, что ref.update () возвращает обещание.

Таким образом, очередь обновлений выполняется асинхронно с базой данных, когда клиент уходит.

Чтобы решить эту проблему, я бы использовал Promise.all () для ожидания всех обновлений завершено.

firebase.firestore().collection('post').where('uid','==',user.uid).get()
   .then((querysnapshot)=>{
       const promises = [];
       querysnapshot.forEach((doc)=>{
           promises.push(doc.ref.update({
               userinfo: {nickname:nickname1,username:username1,intro:intro1}
           });
       });
       Promise.all(promises).then(()=>{window.location.href='/'+username1;});
   });

Или с использованием синтаксиса await (я думаю, что его легче поддерживать и понимать):

const querysnapshot = await firebase.firestore().collection('post').where('uid','==',user.uid).get();

const promises = [];
querysnapshot.forEach((doc)=>{
   promises.push(doc.ref.update({
      userinfo: {nickname:nickname1,username:username1,intro:intro1}
   });
});
await Promise.all(promises);
window.location.href='/'+username1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...