Estoy escribiendo una función de nube de Firebase en node.JS que lee datos de usuario de Firebase Firestore. No puedo insertar los valores de los tokens en la matriz de tokens y devolver todos los tokens al final de la función. Mi código es el siguiente:
function getTokens(subscribers) { return new Promise(async function (resolve, reject) { const tokenArray = []; subscribers.forEach(async (subscriber) => { await firestore .collection('users') .doc(subscriber) .get() .then((user) => { console.log("Getting user data for user: ", user); const tokens = user.data().tokens; if (tokens) { tokens.forEach((token) => { console.log("Adding token to token array"); // data is available here but does not push into tokenArray tokenArray.push(token); }); } }).catch((error) => { console.error(error); reject(error); }); }); console.log("Token Array -- Final: ", tokenArray); resolve(tokenArray); }); };
El código OP se puede corregir y hacer más conciso de la siguiente manera:
async function getTokens(subscribers) { const getUser = subscriber => firestore.collection('users').doc(subscriber).get(); const promises = subscribers.map(getUser); const users = await Promise.all(promises); return users.map(user => user.data().tokens).flat() }
Algunas notas:
async
, ya que incluye una esperaPromise.new()
, get()
() de Firestore devuelve una promesaget
promesas en una matriz con map
y ejecútelas con Promise.all()
data.tokens
produce una matriz de matrices. Aplanarlo y listo.catch
que solo tira, es como no tener atrapadaNo puede usar async-await
await en un bucle forEach
. Intente mapear una matriz de promesas y luego use Promise.all()
como se muestra a continuación:
function getTokens(subscribers) { return new Promise(async function (resolve, reject) { const subscribersDocs = await Promise.all( subscribers.map((subscriber) => { return firestore.collection("users").doc(subscriber).get(); }) ); const tokenArray = subscribersDocs.reduce((acc, curr) => { const tokens = curr.data().tokens; if (tokens) { acc = acc.concat(tokens); } return acc; }, []); console.log("Token Array -- Final: ", tokenArray); resolve(tokenArray); }); }
También consulte: Uso de async/await con un bucle forEach