es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cloud Function de Google se termina antes de que se haya finalizado la actualización en Firestore.

Tengo una Función de Fondo en la Nube que obtiene algunos datos de una fuente externa. Luego, se supone que estos datos se almacenan en un documento de Firestore. Pero nunca se guardan. El documento permanece sin cambios. Aquí está mi código:

public class MyFunction implements BackgroundFunction<pubsubmessage> {

   @Override
   public void accept(PubSubMessage message, Context context) {
      // extrayendo datos de fuente externa
      MyClass myObject = getData();
      // db es el objeto Firestore y se inicializó anteriormente
      CollectionReference colRef = db.collection(MI_COL);
      DocumentReference docRef = colRef.document(MI_DOC);
      ApiFuture<writeresult> future = docRef.set(myObject);
      ApiFutures.addCallback(future,
         new ApiFutureCallback<writeresult>() {
            @Override
            public void onFailure(Throwable throwable) {
               logger.log(Level.SEVERE,
                  "Error al actualizar el objeto en Firestore", throwable);
            }

           @Override
           public void onSuccess(WriteResult writeResult) {
              logger.info("Documento del objeto actualizado... HECHO");
           }
        }, Runnable::run);
   }
}

Los registros de onFailure y onSuccess nunca aparecen en los registros en el panel de Firebase. Parece que la función termina antes de que finalice el proceso de escritura. Los registros no contienen errores y los datos de la fuente externa se extraen correctamente.

¿Cómo puedo asegurarme de que la función no termine antes de que finalice el proceso de escritura?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    El problema con el código es que no espera a que el future se complete. Por lo tanto, la función se termina antes de que finalice el proceso de escritura. Para asegurarse de que la función no termine antes de que se complete el proceso de escritura, necesitamos usar el método get() de la clase ApiFuture. Esto bloqueará el subproceso actual hasta que se complete la mutación.

    Aquí está el código modificado con los cambios sugeridos:

    public class MyFunction implements BackgroundFunction<pubsubmessage> {
    
       @Override
       public void accept(PubSubMessage message, Context context) {
          // pulling data from external source
          MyClass myObject = getData();
          // db is the Firestore object and was initialized earlier
          CollectionReference colRef = db.collection(MY_COL);
          DocumentReference docRef = colRef.document(MY_DOC);
          ApiFuture<writeresult> future = docRef.set(myObject);
    
          try {
              // Block on the write operation by calling get() on the future
              future.get();
              logger.info("Update Object Document ... DONE");
          } catch (InterruptedException | ExecutionException e) {
              logger.log(Level.SEVERE, "Failed to Update Object to Firestore", e);
          }
       }
    }
    

    Al llamar a future.get() dentro de un bloque try-catch, el subproceso actual se bloqueará hasta que se complete la operación de escritura. Si la operación falla, el bloque catch registrará el error. Si tiene éxito, el registro mostrará “Update Object Document … DONE”. Con estos cambios, la función debería completar el proceso de escritura antes de terminar.

Comments are closed.