В вашей облачной функции есть две проблемы:
Во-первых, вы не можете напрямую использовать объект 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.');
});
});