Firebase数据校验莫名返回null问题求助
看起来你遇到的问题根源在于Locale变量初始化时机不正确,导致卸载重装后首次校验数据库时,拼接的路径不符合预期,进而误判数据不存在进入else分支。咱们一步步拆解问题和解决方案:
核心问题分析
Locale变量未提前初始化
你的代码中,locale变量仅在进入else分支时才被赋值为Locale.getDefault().getLanguage()。但卸载重装后SharedPreferences被清空,首次调用CheckIfDataExists()时,locale可能是未初始化的默认值(比如null)。这会导致拼接数据库路径时生成URL_planes_null,而数据库中实际存储的是对应系统语言的路径(比如URL_planes_en),自然查不到数据,触发else分支。SharedPreferences默认值依赖未初始化变量
代码中sharedPrefsDefault.getString(getString(R.string.str_language),locale)这部分,当SharedPreferences无数据时,默认值用的是未初始化的locale,进一步加剧了路径错误的问题。嵌套异步监听的潜在风险
嵌套两个addListenerForSingleValueEvent会增加调试复杂度,虽然切换账号时正常,但这种逻辑容易隐藏异步时序问题。
修复方案
1. 提前初始化Locale变量
在调用CheckIfDataExists()之前,先完成Locale的初始化,确保首次校验时路径正确:
// 在Activity/Fragment的onCreate或启动流程中提前执行 String systemLocale = Locale.getDefault().getLanguage(); sharedPrefsDefault.edit().putString(getString(R.string.str_language), systemLocale).apply();
2. 修改SharedPreferences默认值为系统Locale
把所有sharedPrefsDefault.getString(...)的默认值直接替换为系统Locale,不再依赖未初始化的变量:
// 原代码:.child("URL_planes_"+sharedPrefsDefault.getString(getString(R.string.str_language),locale)) // 修改后: .child("URL_planes_"+sharedPrefsDefault.getString(getString(R.string.str_language), Locale.getDefault().getLanguage()))
3. 合并数据库查询(优化建议)
将两个嵌套的数据库查询合并为一次,减少异步嵌套的复杂度:
private void CheckIfDataExists(){ String currentLocale = sharedPrefsDefault.getString(getString(R.string.str_language), Locale.getDefault().getLanguage()); Log.e("CurrentLocale", "Using locale: " + currentLocale); // 一次性查询planes和cars节点 mDatabase.child("Users") .child(mAuth.getCurrentUser().getUid()) .child("URL_UserFiles") .addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { DataSnapshot planesSnapshot = dataSnapshot.child("URL_planes_"+currentLocale); DataSnapshot carsSnapshot = dataSnapshot.child("URL_cars_"+currentLocale); if (planesSnapshot.getValue() != null && carsSnapshot.getValue() != null) { Log.e("Descarga","DATA EXISTS"); // 数据存在时的下载逻辑... } else { Log.e("Descarga2","DATA DOES NOT EXIST"); String systemLocale = Locale.getDefault().getLanguage(); sharedPrefsDefault.edit().putString(getString(R.string.str_language), systemLocale).apply(); // 数据不存在时的默认数据下载逻辑... } } @Override public void onCancelled(DatabaseError databaseError) { Log.e("DatabaseError", "Failed to check data: " + databaseError.getMessage()); } }); }
4. 增加日志调试
在拼接路径前后添加日志,确认路径是否与Firebase控制台中的存储路径一致:
String planesDbPath = "Users/" + mAuth.getCurrentUser().getUid() + "/URL_UserFiles/URL_planes_" + currentLocale; Log.e("DatabasePath", "Checking planes path: " + planesDbPath);
验证点
- 卸载重装后,查看启动日志,确认拼接的数据库路径是否与Firebase中存储的路径匹配。
- 检查SharedPreferences在首次启动时是否被正确赋值为系统Locale。
内容的提问来源于stack exchange,提问作者Gastón Saillán

