Repository navigation
Read numeric WS dates as epoch nanoseconds - #87
Conversation
The v2 gateway Feeds connects to (/api/v2/connect) encodes every time field as integer epoch nanoseconds, but LenientDateAdapter read numbers as epoch millis. StreamConnectedUser.createdAt, updatedAt and lastActive came out tens of millions of years in the future. No gateway sends numeric dates in any other unit (chat /connect and video /video/connect send RFC3339 strings), so a number is now always nanoseconds. Writes stay in millis so the health check payload sent back to the server is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PR checklist ✅All required conditions are satisfied:
🎉 Great job! This PR is ready for review. |
|
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. 🧰 Additional context used📚 Code guidelines (1)No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (3)
Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review. WalkthroughNumeric dates are now read as epoch nanoseconds and converted to milliseconds. RFC3339 string and null handling remain unchanged. Outbound dates remain epoch milliseconds. ChangesNumeric date parsing
Priority: ➖ Normal Estimated code review effort: 2 (Simple) | ~10 minutes Change: Bug fix Suggested reviewers: Merge Risk: ⚪ Minimal · up to No actionable merge-blocking issue is established; the change is mergeable after normal checks. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to The date correction does not show a new authorization or data-access path. However, timestamps echoed in connection heartbeats change, and server acceptance of those values is not independently confirmed. Retained concerns
Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
Resilience and Maintainability Implications
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 2📝 Generate docstrings 💡
🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. A rabbit checks the dates at night, Comment |
|
🚀 Available in v5.1.1 |



Goal
Closes AND-1516. The connected user returned by Feeds'
connect()has nonsense dates:The v2 gateway (
/api/v2/connect, used by Feeds) writes every time field as integer epoch nanoseconds ("created_at":1755586996702859000), andLenientDateAdapterread any number as epoch millis.This is pre-existing, not a regression from the 4.x to 5.x move: the old
DateMillisAdaptermade the same assumption.Why nanoseconds unconditionally
I considered checking the number's magnitude to tell the units apart, but there is nothing to tell apart. On the backend, the encoding depends only on the route's JSON profile, and no client option changes it:
/api/v2/connect(Feeds)/connect(Chat)/video/connect(Video)The encoder behind the v2 profile writes
t.UnixNano(), and writes0for zero or pre-1970 times. No path writes millis or micros. The Feeds clients on other platforms already rely on this: feeds-js divides numbers by 1e6, and iOS core divides by 1e9. Neither checks the magnitude.Implementation
LenientDateAdapter.fromJsonreadsNUMBERas epoch nanoseconds, truncated to millis forDate. The string branch is unchanged.toJsonstill writes millis. The health check sends the connected event back to the server, so this keeps the outbound payload byte-for-byte what it is today. Reads and writes now use different units, so writing a date and reading it back no longer returns the same value; nothing in production does that. The KDoc explains the asymmetry.Full precision (
Instant) was considered and left out:StreamConnectedUserexposesDatepublicly, nothing needs sub-millisecond precision on these fields, and the Feeds models already truncate to millis.Testing
./gradlew :stream-android-core:testDebugUnitTest: 757 tests, 0 failures.connection.oktest built from a real Feeds handshake payload, plus a test that0reads as the epoch.createdAt=Aug 19 2025,updatedAt=Dec 15 2025andlastActiveset to the current time, and the health check exchange still works.🤖 Generated with Claude Code
Summary by CodeRabbit