Триггер Firebase возвращает другой ключ узла для вызова обновления

Моя структура базы данных выглядит так. Я пытаюсь написать триггер Firebase, который при обновлении любой части узла '/ SCORES' получит RoundScore для PlayerID и обновит существующую запись.

"SCORES" : {
       "2017" : {
         "Round_1" : {
           "3" : {
             "Emoji" : "",
             "PlayerName" : "Person A",
             "RoundScore" : 100
               },
           },
       },
   },

"SELECTIONS" : {
    "2015" : {
      "Round_1" : {
        "TEAM A" : {
          "18" : {
            "emoji" : " ",
            "playerName" : "Person A",
            "position" : "POS"
          },
          "19" : {
            "emoji" : " ",
            "playerName" : "Person B",
            "position" : "POS"
          }
     },
        "TEAM B" : {
          "54" : {
            "emoji" : " ",
            "playerName" : "Person C",
            "position" : "POS"
          },
          "89" : {
            "emoji" : " ",
            "playerName" : "Person D",
            "position" : "POS"
          }
     },
        "TEAM C" : {
          "227" : {
            "emoji" : " ",
            "playerName" : "Person E",
            "position" : "POS"
          },
          "234" : {
            "emoji" : " ",
            "playerName" : "Person F",
            "position" : "POS"
          }
     },
        "TEAM D" : {
          "239" : {
            "emoji" : " ",
            "playerName" : "Person G",
            "position" : "POS"
          },
          "280" : {
            "emoji" : " ",
            "playerName" : "Person H",
            "position" : "POS"
          }
        }
      }
    }
  }
}

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

"SCORES" : {
        "2017" : {
          "Round_1" : {
            "3" : {
              "Emoji" : "", <------------ DUPLICATE FROM HERE
              "PlayerName" : "Person A",
              "RoundScore" : 100 <------------ AND HERE
                },
            },
        },
    },

    "SELECTIONS" : {
        "2015" : {
          "Round_1" : {
            "TEAM A" : {
              "3" : {
                "emoji" : "", <------------ INSERT HERE
                "playerName" : "Person A",
                "position" : "POS"
                "RoundScore" : 100 <------------ AND HERE
              },
            },
        },
    }

До сих пор то, что я написал, работает только для жестко запрограммированного идентификатора команды (КОМАНДА A в приведенном выше примере).

exports.whenScoresUpdate = functions.database
    .ref('/SCORES/{yearId}/{roundId}/{playerId}')
    .onCreate((snap, context) => {  
        const newScoreData = snap.val();
        const yearId = context.params.yearId;
        const roundId = context.params.roundId;
        const playerId = context.params.playerId;
        const scoreObj = {
            "RoundScore" : newScoreData.RoundScore,
            "Emoji" : newScoreData.Emoji,
        }; 
    return admin.database().ref('/SELECTIONS/' + yearId + '/' + roundId + '/{teamId}/' + playerId).update(scoreObj);
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
54
1

Ответы 1

Вы действительно недалеко от этого! Следующий код должен работать. Вот пара замечаний:

  • Поскольку вы хотите запускать «когда любая часть узла '/ SCORES' обновления», вам следует использовать другой триггер, который является onCreate(), например onUpdate(). Обратите внимание, что тогда вам придется использовать change.after.val(); вместо snap.val() ;.
  • Вы должны найти способ установить значение teamId. Это не сработает: ...roundId + '/{teamId}/' + playerId....
  • Вы должны поймать любой возможный Promise.reject из update()

    exports.whenScoresUpdate = functions.database
      .ref('/SCORES/{yearId}/{roundId}/{playerId}')
      .onUpdate((change, context) => {

        const newScoreData = change.after.val();

        const yearId = context.params.yearId;
        const roundId = context.params.roundId;
        const playerId = context.params.playerId;

        const teamID = "A"; //<- adapt according to your needs

        const scoreObj = {
            "RoundScore": newScoreData.RoundScore,
            "Emoji": newScoreData.Emoji,
        };

        return admin.database().ref('/SELECTIONS/' + yearId + '/' + roundId + '/' + teamId + '/' + playerId).update(scoreObj)
            .catch(error => {
                console.info(error);
                //...
            });

       });

Привет, Рено, да, если я жестко запрограммирую идентификатор команды, как у вас const teamID = "A";, он будет работать нормально. Однако это не сработает для моего приложения, так как у меня есть сотни очков, которые принадлежат игрокам, живущим под несколькими идентификаторами teamID. Поэтому мне нужно, чтобы это была переменная, где находится playerID в узле SELECTIONS.

Adam Stewart 11.06.2018 07:14

@AdamStewart трудно помочь, потому что это действительно то, что полностью зависит от потребностей вашего бизнеса. Как узнать, в какую команду (а) это должно быть записано, когда вы пишете в узел SCORES ??

Renaud Tarnec 11.06.2018 07:43

Узел SELECTIONS содержит все соответствующие playerID под каждым teamID. Я обновил исходную структуру постов, чтобы представить большее количество команд.

Adam Stewart 11.06.2018 07:50

Ладно, я понял. Самым простым решением было бы продублировать значение teamId в пользовательских подузлах в узле SCORES. Эта деромализация является классической для моделирования данных NoSQL. Затем вы получаете доступ к нему прямо в своей облачной функции. Другой способ - найти в вашей функции группу с запросом, к которому вы бы связали метод update().

Renaud Tarnec 11.06.2018 08:03

В случае, если пользователь является частью нескольких команд, у вас может быть главный узел с подузлами пользователей, который содержит список всех команд, к которым принадлежит пользователь. И затем, снова в функции, вы начинаете с запроса этого узла, чтобы получить набор команд, а затем вы записываете на разные узлы SELECTIONS/../../{team} с помощью update().

Renaud Tarnec 11.06.2018 08:46

@AdamStewart Привет, ты наконец решил свою проблему?

Renaud Tarnec 18.06.2018 22:02

Другие вопросы по теме