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.

La suscripción de colección devuelve nulo en la marca temporal del servidor.

Estoy agregando documentos a una subcolección llamada workReports mientras estoy suscrito a ella.

Método para la consulta:

getWorkReportsByProjectId(projectId: string): Observable<ProjectWorkReport[]> {

return this.db
    .collection("projects")
    .doc(projectId)
    .collection<ProjectWorkReport>(
      "workReports", 
      ref => ref.where("invalid", "==", false).orderBy("createdAt", "desc")
    )
    .valueChanges({ idField: "id" });
}

Método para la creación (obsérvese createdAt):

createProjectWorkReport(projectId: string, workReport: ProjectWorkReport): Promise<DocumentReference> {
  return this.db
    .collection("projects")
    .doc(projectId)
    .collection<ProjectWorkReport>("workReports")
    .add({ ...workReport, createdAt: firebase.firestore.FieldValue.serverTimestamp() });
}

Mi suscripción (solo registro el resultado):

this.projectsService.getWorkReportsByProjectId(projectId)
  .pipe(takeUntil(this.destroyed$))
  .subscribe((reports) => {
    console.log(reports);
  });

Esto es lo que se está registrando. El elemento en la posición 0 es el nuevo debido a orderBy("createdAt", "desc"), pero su propiedad createAt es nula, pero si hago cambios en la BD o hago la consulta de nuevo, los nuevos resultados tienen ese createdAt de manera normal (y null en el nuevo si hago otra creación).

Mi conjetura es que Firestore tiene en cuenta la sentinela de marca de tiempo independientemente de la creación del documento, y la suscripción se activa antes de que se establezca la marca de tiempo.

¿Estoy haciendo algo mal? Y si mi conjetura es correcta, ¿qué podría hacer para arreglarlo?

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Es posible que el indicador de marca temporal de Firestore esté afectando el comportamiento observado, causando que la suscripción se active antes de que se establezca el campo createdAt. Una solución para garantizar que el campo createdAt esté presente y se establezca correctamente en el primer documento emitido por el observable es modificar el método createProjectWorkReport para que espere a que se resuelva la promesa devuelta por FieldValue.serverTimestamp() antes de agregar el documento a la colección. Esto se puede lograr utilizando la sintaxis async/await de la siguiente manera:

    async createProjectWorkReport(projectId: string, workReport: ProjectWorkReport): Promise<documentreference> {
      const timestamp = await firebase.firestore.FieldValue.serverTimestamp();
      return this.db
        .collection("projects")
        .doc(projectId)
        .collection<projectworkreport>("workReports")
        .add({ ...workReport, createdAt: timestamp });
    }
    

    Al esperar a que se resuelva la promesa de la marca temporal antes de agregar el documento a la colección, se garantiza que el campo createdAt se establezca correctamente antes de crear el documento. Esto debería garantizar que el primer documento emitido del observable siempre tenga un campo createdAt válido, incluso si otros documentos en la colección no tienen este campo debido al momento de su creación.

Comments are closed.