Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

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

Đang mở Phù hợp với người mới
#14,635 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
75/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
java
Lĩnh vực
backend, databases

Hướng nghiên cứu

Bắt đầu tại java-firestore/google-cloud-firestore/src/main/java/com/google/cloud/firestore/UserDataConverter.java, ở phần chuyển đổi encodeValue được liên kết trong issue, và so sánh với com.google.cloud.Timestamp.of(Date). Thêm hoặc tìm một kiểm thử hồi quy cho các ngày trước Unix epoch, chẳng hạn new Date(-1500), rồi xác minh rằng timestamp được mã hóa có nanos không âm. Hoàn tất khi có thể ghi ngày mà không gặp lỗi timestamp không hợp lệ của emulator; issue không nêu tên tệp kiểm thử.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

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.

Ngôn ngữ chính
Java
Star
2.1k
Fork
1.2k
Merge trung bình
2 ngày 16 giờ
Pull request đã merge (30 ngày)
126

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của googleapis/google-cloud-java

Tất cả issue của googleapis/google-cloud-java

Issue tương tự

Thêm issue về Java

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.