You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Database][Android] SIGSEGV in Database::DeleteInternal when embedded bridge-class init fails; FindClassInFiles passes JNI-form names to loadClass on Android #1936
[Database][Android] SIGSEGV in Database::DeleteInternal when embedded bridge-class init fails; FindClassInFiles passes JNI-form names to loadClass on Android
SDK: Firebase C++ SDK 13.12.0, Realtime Database (libFirebaseCppApp-13_12_0.so), arm64 Android.
Two related defects, one crash. Reporting both together because the second turns the first from "error return" into "process death".
1. Init failure crashes instead of returning an error (the SIGSEGV)
When Database::GetInstance cannot finish DatabaseInternal init (in our case: embedded Java bridge classes fail to resolve, see §2), the code path ends in delete database → Database::DeleteInternal, which dereferences a null App* (MakeKey(app=null) → app->name()).
Tombstone (deterministic, every run once the init fails):
Expected: init failure returns an error / null instance. Actual: SIGSEGV. This half is environment-independent — any init failure ends in a crash rather than a diagnosable error, which is also what made §2 so hard to root-cause (no error, just death).
2. Android branch of FindClassInFiles skips the slash→dot conversion the desktop branch does
app/src/util_android.cc, FindClassInFiles (verified on current main):
ClassLoader.loadClass takes binary names (dotted). On typical standalone apps ART tolerates the slashed form so nobody notices; under a custom class-loader setup the lookup fails. Preceding log line in our runs:
E firebase: Java class com/google/firebase/database/internal/cpp/CppTransactionHandler not found.
Suggested fix: the same 3-line std::replace in the Android branch — makes both branches consistent, zero behavior change where lookup already succeeds.
Environment (disclosed so this isn't mis-triaged)
The game runs hosted in another app's process (launcher creates the game context via createPackageContext and hosts its activity). That is why the class-loader topology differs from standalone and why §2 bites here first. But §1 needs no hosted setup to matter: any GetInstance init failure on any app crashes today. And §2 is a contract violation that only happens to work standalone.
Happy to attach the full tombstone + logcat and to test a patched build. Thanks for the SDK.
Hi @Tb1281, thanks for the detailed report. It pointed straight at both problems. I've opened #1947, which fixes both:
Crash on failed init:Database::DeleteInternal() no longer dereferences the null App* when initialization fails, so GetInstance() fails with an error instead of a SIGSEGV. Functions and Storage had the same bug and are fixed too.
Class lookup: the Android branch of FindClassInFiles() now passes the binary name (a.b.C) to ClassLoader.loadClass(), as you suggested. FindOrLoadClassFromLoaders() had the same problem and is fixed too; FindClass() tries it before FindClassInFiles().
You offered to test a patched build. Since you're on Unity, that means building the Firebase Unity SDK against the patched C++ sources. The simplest way is to apply the fix to 13.8.0, the version you already use. The build output then replaces your current Firebase files directly, with no upgrade. (The PR targets main, which is 14.x, and 14.0.0 has breaking changes such as Android minSdkVersion 24.) I checked that the fix applies cleanly on top of v13.12.0 and that the changed files compile there, so it should work on the version you're using.
Build a patched 13.8.0 Unity SDK (Android)
Note: I put these instructions together with Claude, based on the firebase-unity-sdk sources and its CI configuration. I haven't gone through them myself, so some steps may need adjusting.
The C++ checkout must be named firebase-cpp-sdk and sit next to firebase-unity-sdk. build_zips.py picks it up from there automatically. Otherwise, set FIREBASE_CPP_SDK_DIR to its path.
2. Build the Android zip. List every Firebase product your game uses: they are all linked into the single libFirebaseCppApp-13_12_0.so, so a product you leave out would be missing at runtime.
cd firebase-unity-sdk
pip install -r scripts/gha/requirements.txt
python scripts/build_scripts/build_zips.py --platform=android --apis=database,auth
# Adjust --apis to your products. Add --unity_root=<path to Unity># if Unity isn't installed in the default location.
The result is android_unity/firebase_unity-13.12.0-Android.zip.
3. Put it into your project. The Android libraries are packaged as .srcaar files under Firebase/m2repository/com/google/firebase/, both in the zip and in your project's Assets/. Back up your project, replace Assets/Firebase/m2repository with the zip's Firebase/m2repository, then run Assets → External Dependency Manager → Android Resolver → Force Resolve and rebuild the app.
What to look for
The SIGSEGV in Database::DeleteInternal should be gone in all cases. If initialization still fails for some other reason, GetInstance now reports an error instead of crashing, and logcat should show the real cause.
With the class-name fix, CppTransactionHandler should load in your hosted-process setup, and Database should initialize normally. To see the class loading in logcat, set Firebase.FirebaseApp.LogLevel = Firebase.LogLevel.Debug; before using Firebase and look for lines like Load class com.google.firebase.database.internal.cpp.CppTransactionHandler (a.k.a. com/google/...).
It would help a lot if you could post the result in this thread. If anything still fails, please attach the logcat and the tombstone.
Alternative: build against the PR itself (14.x) with GitHub Actions
If you'd rather not build locally, you can fork firebase/firebase-unity-sdk and run the Firebase Unity SDK build workflow on your fork (Actions → Run workflow) with firebase_cpp_sdk_version set to refs/pull/1947/head, platforms set to Android, and apis set to your products. This builds against the PR branch, so you get a 14.x SDK and would need to upgrade your project. I haven't tested this route myself.
Hi Aleksey, thank you for confirming both problems and for opening #1947 — great to see the analysis validated, and impressively fast.
One clarification about testing, though: I am not the game's developer. I work on a third-party Android launcher/modding setup that hosts the game process, so I don't have the game's Unity project and can't rebuild it with a patched Firebase SDK. The embedded libFirebaseCppApp-13_12_0.so in the game can only be replaced by the game's developer shipping an SDK update, so I'm afraid I can't test the patched build the way you described.
What I can say from my side: for our launcher's own embedded bridge jar, we already worked around the class-order symptom by defining classes in supertype-first order, which resolved the CppChildEventListener failures in our hosted-process setup. But the null-deref crash on failed init lives in the game's own SDK, so only an SDK update fixes that path for existing games.
One question: is there any plan to backport this fix to a 13.x release, or will it only land in 14.x? A 13.x backport would matter a lot for games still on 13.12.0 — otherwise they would have to take the 14.0.0 breaking changes (e.g. minSdk 24) to get the fix.
Thanks for clarifying, and for explaining the workaround on your side.
As an external contributor I can't decide whether this gets backported to 13.x. That's up to the Firebase maintainers. I'll leave that question to them here.
Activity
Add release notes for firebase#1936 fixes
Fix crash on failed init and class lookup with custom class loaders
Add release notes for firebase#1936 fixes
AlekseyAzarov commentedon Oct 24, 2026
Hi @Tb1281, thanks for the detailed report. It pointed straight at both problems. I've opened #1947, which fixes both:
Database::DeleteInternal()no longer dereferences the nullApp*when initialization fails, soGetInstance()fails with an error instead of a SIGSEGV. Functions and Storage had the same bug and are fixed too.FindClassInFiles()now passes the binary name (a.b.C) toClassLoader.loadClass(), as you suggested.FindOrLoadClassFromLoaders()had the same problem and is fixed too;FindClass()tries it beforeFindClassInFiles().You offered to test a patched build. Since you're on Unity, that means building the Firebase Unity SDK against the patched C++ sources. The simplest way is to apply the fix to 13.8.0, the version you already use. The build output then replaces your current Firebase files directly, with no upgrade. (The PR targets
main, which is 14.x, and 14.0.0 has breaking changes such as AndroidminSdkVersion24.) I checked that the fix applies cleanly on top ofv13.12.0and that the changed files compile there, so it should work on the version you're using.Build a patched 13.8.0 Unity SDK (Android)
Prerequisites (as for the official build, see the firebase-unity-sdk README):
absl-pyANDROID_NDK_HOMEandNDK_ROOTpointing to itJAVA_HOMEThe upstream docs recommend macOS for the Android build, but Linux and Windows are supported.
1. Clone both repos side by side at 13.12.0 and apply the fix:
The C++ checkout must be named
firebase-cpp-sdkand sit next tofirebase-unity-sdk.build_zips.pypicks it up from there automatically. Otherwise, setFIREBASE_CPP_SDK_DIRto its path.2. Build the Android zip. List every Firebase product your game uses: they are all linked into the single
libFirebaseCppApp-13_12_0.so, so a product you leave out would be missing at runtime.The result is
android_unity/firebase_unity-13.12.0-Android.zip.3. Put it into your project. The Android libraries are packaged as
.srcaarfiles underFirebase/m2repository/com/google/firebase/, both in the zip and in your project'sAssets/. Back up your project, replaceAssets/Firebase/m2repositorywith the zip'sFirebase/m2repository, then run Assets → External Dependency Manager → Android Resolver → Force Resolve and rebuild the app.What to look for
Database::DeleteInternalshould be gone in all cases. If initialization still fails for some other reason,GetInstancenow reports an error instead of crashing, and logcat should show the real cause.CppTransactionHandlershould load in your hosted-process setup, and Database should initialize normally. To see the class loading in logcat, setFirebase.FirebaseApp.LogLevel = Firebase.LogLevel.Debug;before using Firebase and look for lines likeLoad class com.google.firebase.database.internal.cpp.CppTransactionHandler (a.k.a. com/google/...).It would help a lot if you could post the result in this thread. If anything still fails, please attach the logcat and the tombstone.
Alternative: build against the PR itself (14.x) with GitHub Actions
If you'd rather not build locally, you can fork
firebase/firebase-unity-sdkand run the Firebase Unity SDK build workflow on your fork (Actions → Run workflow) withfirebase_cpp_sdk_versionset torefs/pull/1947/head,platformsset toAndroid, andapisset to your products. This builds against the PR branch, so you get a 14.x SDK and would need to upgrade your project. I haven't tested this route myself.Tb1281 commentedon Oct 24, 2026
Hi Aleksey, thank you for confirming both problems and for opening #1947 — great to see the analysis validated, and impressively fast.
One clarification about testing, though: I am not the game's developer. I work on a third-party Android launcher/modding setup that hosts the game process, so I don't have the game's Unity project and can't rebuild it with a patched Firebase SDK. The embedded
libFirebaseCppApp-13_12_0.soin the game can only be replaced by the game's developer shipping an SDK update, so I'm afraid I can't test the patched build the way you described.What I can say from my side: for our launcher's own embedded bridge jar, we already worked around the class-order symptom by defining classes in supertype-first order, which resolved the
CppChildEventListenerfailures in our hosted-process setup. But the null-deref crash on failed init lives in the game's own SDK, so only an SDK update fixes that path for existing games.One question: is there any plan to backport this fix to a 13.x release, or will it only land in 14.x? A 13.x backport would matter a lot for games still on 13.12.0 — otherwise they would have to take the 14.0.0 breaking changes (e.g. minSdk 24) to get the fix.
Thanks again for the quick turnaround.
AlekseyAzarov commentedon Oct 24, 2026
Thanks for clarifying, and for explaining the workaround on your side.
As an external contributor I can't decide whether this gets backported to 13.x. That's up to the Firebase maintainers. I'll leave that question to them here.