Firebase Realtime Database Android: keepSynced(true) + get() causes "listen() called twice for same QuerySpec" AssertionError
I am using Firebase Realtime Database in an Android app.
Firebase BoM:
34.16.0
Persistence is not enabled.
When I use keepSynced(true) and then call get() on the same reference, I get this crash:
> java.lang.AssertionError: hardAssert failed: listen() called twice for same QuerySpec
Example code:
DatabaseReference ref = FirebaseDatabase.getInstance() .getReference("some/path"); ref.keepSynced(true); ref.get().addOnCompleteListener(task -> { // read data });
The stack trace points to Firebase Database internals:
SyncTree
Repo.keepSynced
PersistentConnectionImpl.listen
I tested multiple paths, but the same pattern appears.
This works:
ref.keepSynced(true); ref.addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(DataSnapshot snapshot) { } @Override public void onCancelled(DatabaseError error) { } });
Question:
Is this a known issue with keepSynced(true) and get()?
This is a known issue indeed, although I'm not entirely sure if it's documented anywhere. The get() call was a pretty late addition to the API meant to fix one an edge-case caching issue that folks regularly bumped into:
get())Unfortunately the get() API then introduced other problems, such as the one you encountered here.
Since a auto-synchronized node isn't affected by that edge-case, using addListenerForSingleValueEvent is indeed a valid workaround.