La función que se muestra a continuación me desconcierta por dos razones:
Al buscar mejores prácticas, encontré una sugerencia de que las actividades en segundo plano se ralentizan después de que finaliza la ejecución de la función ( https://cloud.google.com/functions/docs/bestpractices/tips#do_not_start_background_activities ).
¿Cómo puedo crear una función que termine después de que se haya creado toda la salida y evite la actividad en segundo plano?
¿Hay alguna forma de acelerar el procesamiento get()?
captura de pantalla del panel de funciones de firebase
captura de pantalla de firestore que muestra el documento creado para activar la función
Por favor, eche un vistazo al código:
// The Cloud Functions for Firebase SDK to create Cloud Functions . const functions = require("firebase-functions"); // The Firebase Admin SDK to access Firestore. const admin = require("firebase-admin"); admin.initializeApp(); const db = admin.firestore(); exports.evaluateScore = functions .region('europe-west1') .firestore .document('organizations/{orgId}/persons/{personId}') .onWrite(async (snap, context) => { const newDocument = snap.after.exists ? snap.after.data() : null; const oldDocument = snap.before.exists ? snap.before.data() : null; console.log(`lastName: '${newDocument.personLastName}'; id: '${snap.after.id}'`); // if only newDocument exists if (newDocument != null && oldDocument == null ) { const arrayNameSplit = snap.after.ref.path.split('/'); var orgId = arrayNameSplit[arrayNameSplit.length -3]; var listOfProfiles = newDocument.listOfProfiles; console.log(`listOfProfiles: `, JSON.stringify(listOfProfiles)); for (let i = 0; i < listOfProfiles.length; i++) { db.collection('organizations').doc(orgId).collection('profiles').doc(listOfProfiles[i]).get() .then(docRef => { const profile = docRef.data(); console.log(i, ' profileTitle:', JSON.stringify(profile.profileTitle)) }).catch(e => { console.error('something went wrong', e) }); } } });
Tiene llamadas asincrónicas en su código, pero no le informa al tiempo de ejecución de Cloud Functions sobre eso (a través del valor de retorno). Es muy probable que las llamadas get()
de su base de datos ni siquiera se completen en esta etapa.
Para solucionar ese problema, puede usar await
dentro del bucle o Promise.all
:
exports.evaluateScore = functions .region('europe-west1') .firestore .document('organizations/{orgId}/persons/{personId}') .onWrite(async (snap, context) => { const newDocument = snap.after.exists ? snap.after.data() : null; const oldDocument = snap.before.exists ? snap.before.data() : null; console.log(`lastName: '${newDocument.personLastName}'; id: '${snap.after.id}'`); // if only newDocument exists if (newDocument != null && oldDocument == null ) { const arrayNameSplit = snap.after.ref.path.split('/'); var orgId = arrayNameSplit[arrayNameSplit.length -3]; var listOfProfiles = newDocument.listOfProfiles; console.log(`listOfProfiles: `, JSON.stringify(listOfProfiles)); for (let i = 0; i < listOfProfiles.length; i++) { const docRef = await db.collection('organizations').doc(orgId).collection('profiles').doc(listOfProfiles[i]).get(); const profile = docRef.data(); console.log(i, ' profileTitle:', JSON.stringify(profile.profileTitle)) } } });
Puede haber más problemas con su código, por lo que recomiendo leer la documentación sobre sincronización, asíncronismo y promesas , y cómo crear un ejemplo mínimo, completo y verificable para futuras preguntas.