Hola, soy nuevo en las funciones de la nube de firebase y quiero ordenar una colección, que se almacena en firestore, por un campo y luego escribir en cada documento de la colección la 'posición' (esto debería suceder cada 60 minutos). Después de leer la documentación y algunas sugerencias de Stackoverflow, intenté seguir el enfoque.
exports.scheduledFunctionPosition = functions.pubsub.schedule('every 60 minutes').onRun((context) => { return admin.firestore().collection("example") .orderBy("number", "desc") .get() .then(querySnapshot => { if (!querySnapshot.empty) { for(let i =0;i<querySnapshot.size;i++){ var queryDocumentSnapshotTmp = querySnapshot.docs[i]; queryDocumentSnapshotTmp.ref.update({'position':i+1}); } return null; } else { console.log(""); return null; } });Como mis habilidades de programación no son muy buenas, lo intenté de la manera más fácil, pero creo que hay un problema con la programación asíncrona. Este código funciona perfecto para los documentos con los números más altos. Pero cuando hay demasiados documentos, esta función no actualizará los últimos documentos. ¿Existe alguna solucion para esto?
El .update() también es asíncrono; es probable que deba esperarlo, ya sea usando .then() o cambiando a async/await . Mi estilo personal lo escribiría así:
exports.scheduledFunctionPosition = functions .pubsub .schedule('every 60 minutes') .onRun(async (context) => { //will be returning a PROMISE let QuerySnapshot = await admin.firestore().collection("example") .orderBy("number", "desc") .get(); return QuerySnapshot.empty ? (console.log(""), Promise.resolve(null)) : Promise.all( //Promise.all waits for all promises in an array to complete //returns an array, but we use it for the array of promises QuerySnapshot.docs.map(async (doc, index) => { return doc.ref.update({'position':index+1}) //returns a promise }); });Devolver la Promesa asegura que la función espere a que se completen las operaciones.
También tenga en cuenta que las funciones de la nube tienen un límite de tiempo estricto; el valor predeterminado es de 60 segundos. Pueden expirar si tiene demasiados registros.