镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

ServerValues.resolveDeferredValue has incorrect cast #962

Description

@chrylis
  • Operating System version: Gentoo Linux
  • Firebase SDK version: 9.3.0
  • Library version: 9.3.0 (but the bug goes back to at least 8.1.0)
  • Firebase Product: RTDB

As ServerValue.increment is still not supported by this SDK 4 years after its introduction, I tried implementing it manually. This triggers a ClassCastException inside the SDK due to a bad assumption that the value of the .sv key is always a String.

Steps to reproduce:

  1. Create the data structure for ServerValue.increment as described in documentation (such as the REST documentation):
{
  ".sv": {
    "increment": delta
  }
}
  1. Call setValue using this data structure.

Relevant Code:

var node = databaseNode();
node.setValue(Map.of(".sv", Map.of("increment", delta)), callback);

Error:

2024-06-21T19:58:12,008Z [firebase-database-worker] ERROR c.g.firebase.database.core.RunLoop - Uncaught exception in Firebase Database runloop (9.3.0). Please report to firebase-database-client@google.com
java.lang.ClassCastException: class java.util.HashMap cannot be cast to class java.lang.String (java.util.HashMap and java.lang.String are in module java.base of loader 'bootstrap')
	at com.google.firebase.database.core.ServerValues.resolveDeferredValue(ServerValues.java:44)
	at com.google.firebase.database.core.ServerValues.resolveDeferredValueSnapshot(ServerValues.java:80)
	at com.google.firebase.database.core.Repo.setValue(Repo.java:376)
	at com.google.firebase.database.DatabaseReference$1.run(DatabaseReference.java:305)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:829)

Activity

  1. google-oss-bot commented on Jun 21, 2024

    @google-oss-bot

    I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

  2. rootkiller6788 commented on Sep 24, 2026

    @rootkiller6788

    Ran into this while implementing increment by hand as well. The cast in resolveDeferredValue assumes whatever sits under ".sv" is a string, but {".sv": {"increment": 1}} is a compound server value - the client has no way to resolve that locally, it should just fall through and let the write go to the server, which does understand it. I put together a patch with a test for it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions