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()?

0
Jul 16 at 12:09 PM
User Avatartester
#java#android#firebase#firebase-realtime-database

Accepted Answer

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:

  • https://stackoverflow.com/questions/34486417/firebase-offline-capabilities-and-addlistenerforsinglevalueevent/34487195#34487195
  • https://stackoverflow.com/questions/66072471/what-is-the-difference-between-get-and-addlistenerforsinglevalueevent/66072472#66072472 (although I still need to update that for known issues in get())
  • https://stackoverflow.com/questions/65653735/firebase-query-get-vs-addlistenerforsinglevalueevent-for-single-data-read/65654845#65654845

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.

User AvatarFrank van Puffelen
Jul 16 at 3:13 PM
0