[READ] Step 1: Are you in the right place?
Yes. I believe this is a bug in the Firebase Realtime Database Android SDK.
[REQUIRED] Step 2: Describe your environment
- Android Studio version: Android Studio Quail 2
- Firebase Component: Realtime Database
- Component version: 22.0.1 (Firebase Android BoM 34.16.0)
- Persistence: Disabled
- Platform: Android
- Language: Java
[REQUIRED] Step 3: Describe the problem
Steps to reproduce:
Calling get() immediately after keepSynced(true) on the same DatabaseReference consistently crashes with:
java.lang.AssertionError:
hardAssert failed: listen() called twice for same QuerySpec
The stack trace points to Firebase Realtime Database internals, including:
SyncTree
Repo.keepSynced
PersistentConnectionImpl.listen
Steps to reproduce:
- Create a
DatabaseReference.
- Call
keepSynced(true).
- Call
get() on the same reference.
Expected behavior:
get() should return the current data without crashing.
Actual behavior:
The application crashes with the assertion above.
I can consistently reproduce this on multiple database paths and in different parts of my application. The common factor is always:
keepSynced(true)
followed by
get()
Replacing get() with addListenerForSingleValueEvent() consistently avoids the crash.
There is also a related Stack Overflow discussion:
https://stackoverflow.com/questions/79981289/firebase-realtime-database-android-keepsyncedtrue-get-causes-listen-called-twice-for-same-queryspec
In that discussion, Frank van Puffelen (former Firebase team member) commented:
"Definitely a bug..."
He also explained that get() likely does not correctly check the SyncTree before deciding to fetch data when keepSynced(true) is already active.
Could the Firebase Realtime Database Android SDK team please confirm whether this is a known issue and whether a fix is planned?
Relevant Code:
DatabaseReference ref = FirebaseDatabase.getInstance()
.getReference("test/path");
ref.keepSynced(true);
ref.get().addOnCompleteListener(task -> {
// Read data
});
Working alternative:
DatabaseReference ref = FirebaseDatabase.getInstance()
.getReference("test/path");
ref.keepSynced(true);
ref.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot snapshot) {
// Read data
}
@Override
public void onCancelled(@NonNull DatabaseError error) {
}
});
[READ] Step 1: Are you in the right place?
Yes. I believe this is a bug in the Firebase Realtime Database Android SDK.
[REQUIRED] Step 2: Describe your environment
[REQUIRED] Step 3: Describe the problem
Steps to reproduce:
Calling
get()immediately afterkeepSynced(true)on the sameDatabaseReferenceconsistently crashes with:The stack trace points to Firebase Realtime Database internals, including:
Steps to reproduce:
DatabaseReference.keepSynced(true).get()on the same reference.Expected behavior:
get()should return the current data without crashing.Actual behavior:
The application crashes with the assertion above.
I can consistently reproduce this on multiple database paths and in different parts of my application. The common factor is always:
Replacing
get()withaddListenerForSingleValueEvent()consistently avoids the crash.There is also a related Stack Overflow discussion:
https://stackoverflow.com/questions/79981289/firebase-realtime-database-android-keepsyncedtrue-get-causes-listen-called-twice-for-same-queryspec
In that discussion, Frank van Puffelen (former Firebase team member) commented:
He also explained that
get()likely does not correctly check the SyncTree before deciding to fetch data whenkeepSynced(true)is already active.Could the Firebase Realtime Database Android SDK team please confirm whether this is a known issue and whether a fix is planned?
Relevant Code:
Working alternative: