Проблемы с обновлением документа firestore путем фиксации пакета после функции asyn c - PullRequest
0 голосов
/ 28 марта 2020

Я пишу облачную функцию, которая использует запрос-обещание и cheerio для очистки веб-сайта, а затем сверяет эту информацию с пользовательским документом.

Я не совсем знаком с Javascript и облачными функциями.

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

Эта функция должна l oop для всех пользователей и изменить их документ, если точка данных совпадает. Я не уверен, что способ написания кода является наиболее оптимальным с точки зрения производительности и выставления счетов, если база пользователей становится огромной ... Любые указатели на то, как я мог бы минимизировать влияние на задачу, были бы очень полезны, так как я новичок с JS.

Так вот код:

exports.getV75Results = functions.pubsub.schedule('every 2 minutes').onRun(async (context) => {
    let linkMap = new Map();

    const url = `https://www.example.com`
    const options = {
        uri: url,
        headers: { 'User-Agent': 'test' },
        transform: (body) => cheerio.load(body)
    }

    await rp(options)
        .then(($) => {
            for(let i = 1; i <= 7; i++)
            {
              //Find player from game 
              const lopp1 = $(`#mainContentHolder > div > div.mainContentStyleTrot > div > div.panel-body > table:nth-child(1) > tbody > tr:nth-child(${i}) > td:nth-child(2) > span`).text()
              const lopp1StrR1 = lopp1.replace("(", "");
              const lopp1StrR2 = lopp1StrR1.replace(")", "");
              const lopp1StrR3 = lopp1StrR2.replace(" ", "");
              linkMap.set(i, lopp1StrR3.toUpperCase());
            }
           console.log(linkMap);
           return linkMap;
        }).then(async () => {
           //Start lookup users
           let usersRef = db.collection('fantasyfotball').doc('users');

            usersRef.listCollections().then(collections => {
             collections.forEach( collection => {
               var user = collection.doc(collection.id);
               let batch = new admin.firestore().batch();
               user.get().then(function(doc) {
                 let json = doc.data();
                  //Look in users collection if players document exist
               Object.keys(json).forEach((name) => {      
 
               if(name != null) {
                 //Document with users active fotball players 
                 if(name == 'players') {
                 let i = 0;
                 Object.values(json[name]).forEach((value)  => {
                   i++;
                   if(value.localeCompare(linkMap.get(i)) == 0) {
                    
                     //Loop through user keys and find owned players if user has the correct player
                     Object.keys(json).forEach((map)  => {
                       if(map != null)
                       {
                         //Document with a map of player owned fotball players, each respective player has a key = 'fotball player' and value = '[price, points]'
                         if(map == 'ownedplayers')
                         {
                           Object.entries(json[map]).forEach((players)  => {
                             if(players[0].localeCompare(value) == 0) {
                               console.log(players[1][1]);
 
 
                               //Add points to respective player field
                               //PROBABLY NOT HOW TO CHANGE A DOCUMENT FILED, THIS DOESNT WORK..
                               players[1][1]++;
                             }
                           });
                           //EACH TIME THIS RUNS IT SAYS: "Cannot modify a WriteBatch that has been committed"
                           batch.update(user, {'ownedplayers': json[map]});
                         }
                       }
                     });
                   }
                  });
                 }
                 } else {
                   console.log('user does not have a playermode document.');
                 }
                 });
               });
               return batch.commit().then(function () {
               console.log("Succesfully commited changes.");
               return null;
           });
         });
        });
        }).catch((err) => {
           return err;
        });
  });

Проблемы, с которыми я сталкиваюсь в консоли: «Невозможно изменить зафиксированный WriteBatch». и я не могу изменить и добавить точки на поле игрока внутри документа пользователя.

Это консоль: Console image

Это структура документа пожарного магазина: Firestore structure

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

Приветствия,

1 Ответ

0 голосов
/ 29 марта 2020

Наконец .... мне удалось обновить документ успешно. Я помещаю коммит вне другого ".then ()". Я думал, что попробовал, но угадаю: P

 }).then(() => {
                return batch.commit().then(function () {
                  console.log("Succesfully commited changes.");
                  return null;
               });

Проблема теперь в том, что он фиксирует каждый l oop. Я думаю, что наиболее оптимальным вариантом здесь будет пакетное обновление ALL пользователей перед их фиксацией?

И снова, есть ли более оптимальный способ сделать это с точки зрения минимизации работы и воздействия? Боюсь, что я go слишком глубоко разбираюсь в циклах вместо прямой навигации к документу, но не нашел более простого способа сделать это.

Есть мысли?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...