Firestore простая функция списка лидеров - PullRequest
0 голосов
/ 06 ноября 2018

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

Вот моя текущая функция, которая уже ранжирует их от 1 до 10:

    exports.leaderboardUpdate2 = functions.https.onRequest((req, res) =>{
  const updates = [];
  const leaderboard = {};

  const rankref = admin.firestore().collection('mobile_user');
  const leaderboardRef = admin.firestore().collection('leaderboard');

  return rankref.orderBy("earned_points").limit(10).get().then(function(top10) {
      let i = 0;
      console.log(top10)
      top10.forEach(function(childSnapshot) {
        const r = top10.size - i;
        console.log(childSnapshot)
        updates.push(childSnapshot.ref.update({rank: r}));
        leaderboard[childSnapshot.key] = Object.assign(childSnapshot, {rank: r});
        i++;
        console.log(leaderboard)
      });
      updates.push(leaderboardRef.add(leaderboard));
      return Promise.all(updates);
    }).then(() => {
      res.status(200).send("Mobile user ranks updated");
    }).catch((err) => {
      console.error(err);
      res.status(500).send("Error updating ranks.");
    });
});

Это успешно обновляет узел / mobile_user, где находятся все мои пользователи, но я хочу «экспортировать» этих 10 пользователей в узел списка лидеров после выполнения функции.

(Обратите внимание, что узел списка лидеров должен всегда иметь только 10 записей)

1 Ответ

0 голосов
/ 06 ноября 2018

В вашей облачной функции есть две проблемы:

Во-первых, вы не можете напрямую использовать объект childSnapshot (ни с Object.assign, ни напрямую) для создания нового документа. Вы должны использовать childSnapshot.data(), см. https://firebase.google.com/docs/reference/js/firebase.firestore.DocumentSnapshot

Во-вторых, вы используете childSnapshot.key, тогда как оно должно быть childSnapshot.id, см. Тот же документ, что и выше.

Наконец, обратите внимание, что с вашей структурой кода документ users добавляется как карты в уникальный документ leaderboard. Я не уверен, что это именно то, что вы хотите, поэтому вы можете адаптировать свой код для этого конкретного момента.

Так должно работать следующее:

exports.leaderboardUpdate2 = functions.https.onRequest((req, res) => {
  const updates = [];
  const leaderboard = {};

  const rankref = admin.firestore().collection('mobile_user');
  const leaderboardRef = admin.firestore().collection('leaderboard');

  return rankref
    .orderBy('earned_points')
    .limit(10)
    .get()
    .then(function(top10) {
      let i = 0;
      console.log(top10);
      top10.forEach(function(childSnapshot) {
        const r = top10.size - i;
        updates.push(childSnapshot.ref.update({ rank: r }));
        leaderboard[childSnapshot.id] = Object.assign(childSnapshot.data(), {
          rank: r
        });
        i++;
      });
      updates.push(leaderboardRef.add(leaderboard));
      return Promise.all(updates);
    })
    .then(() => {
      res.status(200).send('Mobile user ranks updated');
    })
    .catch(err => {
      console.error(err);
      res.status(500).send('Error updating ranks.');
    });
});

После вашего комментария, вот новая версия, которая записывает документ в коллекцию leaderboard для каждого mobile_user. Обратите внимание, что мы используем DocumentReference и вместе с методом set() следующим образом: leaderboardRef.doc(childSnapshot.id).set()

exports.leaderboardUpdate2 = functions.https.onRequest((req, res) => {
  const updates = [];
  const leaderboard = {};

  const rankref = admin.firestore().collection('mobile_user');
  const leaderboardRef = admin.firestore().collection('leaderboard');

  return rankref
    .orderBy('earned_points')
    .limit(10)
    .get()
    .then(function(top10) {
      let i = 0;
      console.log(top10);
      top10.forEach(function(childSnapshot) {
        const r = top10.size - i;
        updates.push(childSnapshot.ref.update({ rank: r }));

        updates.push(
          leaderboardRef.doc(childSnapshot.id).set(
            Object.assign(childSnapshot.data(), {
              rank: r
            })
          )
        );

        i++;
      });

      return Promise.all(updates);
    })
    .then(() => {
      res.status(200).send('Mobile user ranks updated');
    })
    .catch(err => {
      console.error(err);
      res.status(500).send('Error updating ranks.');
    });
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...