Hacktoberfest 2026: as issues que os mantenedores marcaram para outubro, abertas e boas para iniciantes. Ver issues do Hacktoberfest

[java-firestore] UserDataConverter encodes a pre-epoch Date with negative nanos, so the write is refused

Aberta Para iniciantes
#14,635 0 comentários 0 reações 0 responsáveis Ver no GitHub

Mantenedores costumam responder em até 1 dia

Ninguém assumiu esta issue ainda.

Avaliação

Dificuldade
2/5
Tempo estimado
1-3 horas
Facilidade para iniciantes
75/100
Tipo de issue
Bug
Clareza
Claramente especificada
Status de atividade
Ativa
Stack de tecnologia
java
Domínio
backend, databases

Direção de pesquisa

Comece em java-firestore/google-cloud-firestore/src/main/java/com/google/cloud/firestore/UserDataConverter.java, na conversão encodeValue vinculada na issue, e compare-a com com.google.cloud.Timestamp.of(Date). Adicione ou localize um teste de regressão para datas anteriores à época Unix, como new Date(-1500), e verifique se o timestamp codificado tem nanos não negativos. O trabalho estará concluído quando for possível gravar a data sem o erro de timestamp inválido do emulador; a issue não especifica um arquivo de teste.

Escrita pelo modelo de indexação a partir do texto da issue.

Descrição

Issue Details

UserDataConverter.encodeValue converts a java.util.Date into a Timestamp proto by truncating the milliseconds toward zero for seconds and putting the remainder in nanos:

https://github.com/googleapis/google-cloud-java/blob/9de611fe5633e9f43c6081754c834cabcd0317bb/java-firestore/google-cloud-firestore/src/main/java/com/google/cloud/firestore/UserDataConverter.java#L149-L157

For a date before the epoch that is not a whole second, the remainder is negative, so the proto carries a negative nanos, which google.protobuf.Timestamp does not allow (nanos must be in [0, 999999999]). new Date(-1500) is sent as seconds: -1, nanos: -500000000, and new Date(-1) as nanos: -1000000. The emulator refuses the write with INVALID_ARGUMENT: Timestamp nanos exceeds limit for field., so a valid Date cannot be written. The same conversion serves every value the library encodes, so a Date field of a POJO and a query filter or cursor on a Date should be affected the same way (not tried).

com.google.cloud.Timestamp.of(Date) already does this conversion correctly (it borrows a second when the remainder is negative), so encodeValue could use it, or Math.floorDiv and Math.floorMod.

Found while building an Apache Flink sink on google-cloud-firestore (flink-gcp/flink-connector-gcp).

Environment

  • OS Type and Version: macOS 26 (arm64)
  • Java Version and JDK Vendor: Eclipse Temurin 17.0.20
  • Firestore emulator: gcr.io/google.com/cloudsdktool/google-cloud-cli:588.0.0-emulators (Native mode, Standard edition); 587.0.0 answers the same

The refusal was measured on the emulator only, not against a production database.

Dependencies

  • Libraries-Bom: 26.90.0
    • google-cloud-firestore 3.49.0
  • Gax: 2.87.0
  • Auth: 1.54.0

The affected code is identical in 3.49.0 and on main.

Reproducer

Run with FIRESTORE_EMULATOR_HOST set.

package repro;

import com.google.cloud.firestore.DocumentReference;
import com.google.cloud.firestore.Firestore;
import com.google.cloud.firestore.FirestoreOptions;
import java.util.Date;
import java.util.Map;

public class PreEpochDate {
  public static void main(String[] args) throws Exception {
    Firestore db = FirestoreOptions.newBuilder().setProjectId("demo").build().getService();
    for (long millis : new long[] {-1000, -1500, -1}) {
      DocumentReference doc = db.collection("dates").document("d" + millis);
      try {
        doc.set(Map.of("t", new Date(millis))).get();
        System.out.println(millis + " ms: written, read back as " + doc.get().get().getTimestamp("t"));
      } catch (Exception e) {
        System.out.println(millis + " ms: " + e.getCause());
      }
    }
    System.exit(0);
  }
}

Logs and Stack Trace

-1000 ms: written, read back as 1969-12-31T23:59:59Z
-1500 ms: com.google.api.gax.rpc.InvalidArgumentException: io.grpc.StatusRuntimeException: INVALID_ARGUMENT: Timestamp nanos exceeds limit for field.
-1 ms: com.google.api.gax.rpc.InvalidArgumentException: io.grpc.StatusRuntimeException: INVALID_ARGUMENT: Timestamp nanos exceeds limit for field.

Behavior

Deterministic: any Date before the epoch whose millisecond value is not a multiple of 1000.

Linguagem predominante
Java
Estrelas
2.1k
Forks
1.2k
Merge médio
2d 16h
PRs com merge (30d)
126

Preparar o ambiente

Primeiros passos

  1. Leia a issue inteira e depois o guia de contribuição do projeto.
  2. Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
  3. Faça um fork do repositório e trabalhe em uma branch.
  4. Abra um pull request que referencie o número da issue.

Mais de googleapis/google-cloud-java

Todas as issues de googleapis/google-cloud-java

Issues semelhantes

Mais issues de Java

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.