Поскольку вы хотите параллельно выполнять несколько асинхронных задач (вызов метода update()
, который возвращает Promise), вам нужно использовать Promise.all()
, какследует:
var getGame = admin.firestore().collection('games');
getGame = getGame
.where('gid', '==', gamePin)
.get()
.then(snapshot => {
if (!snapshot.empty) {
console.log(`BODY: ${JSON.stringify(req.body)}`);
const promises = [];
snapshot.forEach(doc => {
let data = doc.data();
data.id = doc.id;
console.log(`DOC DATA: ${JSON.stringify(data)}`);
const currentNumPlayers = data.playercount;
console.log(`currentNumPlayers: ${JSON.stringify(currentNumPlayers)}`);
const newPlayerCount = +numPlayers + +currentNumPlayers;
console.log(`newPlayerCount: ${JSON.stringify(newPlayerCount)}`);
const newPlayerCountToString = newPlayerCount.toString();
console.log(
`newPlayerCountToString: ${JSON.stringify(newPlayerCountToString)}`
);
var updateGame = admin
.firestore()
.collection('games')
.doc(data.id);
promises.push(
updateGame.update({
playercount: newPlayerCountToString
})
);
});
return Promise.all(promises)
.then(results => {
console.log(`COMPLETED UPDATE: ${JSON.stringify(res)}`);
res.send({
status: 200,
message: 'Game: updated.',
pin: gamePin
});
})
.catch(err => {
console.log(`ERROR IN QUERY: ${JSON.stringify(err)}`);
throw new Error(err);
});
} else {
console.log('could not find a match ', snapshot);
throw new Error('Error. could not find a match');
}
})
.catch(error => {
console.log(error);
res.status(500).send(error);
});
Обновление после вашего комментария : Если вы точно знаете, что Query
("возвращает только один документ)есть только один документ с этим игровым значком "), вы можете использовать свойство docs
объекта QuerySnapshot, которое возвращает" массив всех документов в QuerySnapshot "и выполняет следующие действия:
var getGame = admin.firestore().collection('games');
getGame = getGame
.where('gid', '==', gamePin)
.get()
.then(snapshot => {
if (!snapshot.empty) {
console.log(`BODY: ${JSON.stringify(req.body)}`);
const doc = snapshot.docs[0];
let data = doc.data();
data.id = doc.id;
const currentNumPlayers = data.playercount;
const newPlayerCount = +numPlayers + +currentNumPlayers;
const newPlayerCountToString = newPlayerCount.toString();
return admin.firestore().collection('games').doc(data.id)
.update({
playercount: newPlayerCountToString
})
.then(() => {
console.log(`COMPLETED UPDATE: ${JSON.stringify(res)}`);
res.send({
status: 200,
message: 'Game: updated.',
pin: gamePin
});
})
.catch(err => {
console.log(`ERROR IN QUERY: ${JSON.stringify(err)}`);
throw new Error(err);
});
} else {
console.log('could not find a match ', snapshot);
throw new Error('Error. could not find a match');
}
})
.catch(error => {
console.log(error);
res.status(500).send(error);
});
Второе обновление , см. Комментарии в коде:
exports.addPlayerToGame = functions.https.onRequest((req, res) => {
return cors(req, res, () => {
// Check for POST request
if (req.method !== 'POST') {
res.status(400).send('Please send a POST request');
}
const gamePin = req.body.gamepin;
const numPlayers = req.body.playercount.toString();
admin //Here I would not use a getGame variable
.firestore()
.collection('games')
.where('gid', '==', gamePin)
.get()
.then(snapshot => {
if (!snapshot.empty) {
console.log(`BODY: ${JSON.stringify(req.body)}`);
const doc = snapshot.docs[0];
let data = doc.data();
data.id = doc.id;
const currentNumPlayers = data.playercount;
console.log(
`currentNumPlayers: ${JSON.stringify(currentNumPlayers)}`
);
const newPlayerCount = +numPlayers + +currentNumPlayers;
console.log(`newPlayerCount: ${JSON.stringify(newPlayerCount)}`);
const newPlayerCountToString = newPlayerCount.toString();
console.log(
`newPlayerCountToString: ${JSON.stringify(newPlayerCountToString)}`
);
return admin
.firestore()
.collection('games')
.doc(data.id)
.update({
playercount: newPlayerCountToString
})
.then(() => { //Here, I don't understand why do you return res. The update method returns an empty Promise so just do .then(() => {}}
console.log(`COMPLETED UPDATE`); //Here don't use res, as it is the Response object and represents the HTTP response that an Express app sends when it gets an HTTP request
res.send({
status: 200,
message: 'Game: updated.',
pin: gamePin
});
})
.catch(err => {
console.log(`ERROR IN QUERY: ${JSON.stringify(err)}`);
// throw new Error(err);
res.status(500).send(err); //I am not sure what is better... throwing an Error or sending back a 500 response code.
});
} else {
console.log('could not find a match ', snapshot);
res.send({ status: 400, message: 'Error. could not find a match' });
}
console.log(`END:`);
})
.catch(error => {
console.log(error);
res.status(500).send(error);
});
});
});