You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google Play分发应用Firestore指定字段返回空值,本地调试正常

问题描述

我的应用目前仅在Google Play内部测试轨道发布,通过Android Studio启动运行无异常,但上传至Google Play后,卸载手机上的版本再下载安装,启动时执行以下代码中document.get("Best level")、document.get("Best number of words")、document.get("Best word length")和document.get("Play sounds")均返回null。

相关代码
private static final String FSBESTLEVEL = "Best level";
private static final String FSBESTNUMWORDS = "Best number of words";
private static final String FSBESTWORDLEN = "Best word length";
private static final String FSSOUNDS = "Play sounds";


private void getSettings() {
    spinner.setVisibility(View.VISIBLE);
    mDevIDDocRef.get().addOnCompleteListener(new 
OnCompleteListener<DocumentSnapshot>() {
//        mDevIDDocRef.get(Source.SERVER).addOnCompleteListener(new 
OnCompleteListener<DocumentSnapshot>() {
    @Override
    public void onComplete(@NonNull Task<DocumentSnapshot> task) {
        if (task.isSuccessful()) {
            DocumentSnapshot document = task.getResult();
            assert document != null;
            if (document.exists()) {
                // Handle the legacy Best score field, which was a String.
                // All the documents that contained a non-blank score have
                // already been converted to Long.
                if (document.get(FSBESTSCORE) instanceof String) {
                    updateFieldType(BEGINNER_TIME/1000L);
                    myScore = BEGINNER_TIME/1000;
                } else {
                    myScore = (Long)document.get(FSBESTSCORE);
                }
                level_val = ((Long) Objects.requireNonNull(document.get(FSLEVEL))).intValue();
                if (document.get(FSBESTLEVEL) == null) {
                    best_level_val = 0;
                    updateBestLevel(level_val);
                } else {
                    best_level_val = ((Long)document.get(FSBESTLEVEL)).intValue();
                }
                num_words_val = ((Long) Objects.requireNonNull(document.get(FSNUMWORDS))).intValue();
                if (document.get(FSBESTNUMWORDS) == null) {
                    best_num_words_val = 0;
                    updateBestNumwords(num_words_val);
                } else {
                    best_num_words_val = ((Long)document.get(FSBESTNUMWORDS)).intValue();
                }
                if (document.get(FSBESTWORDLEN) == null) {
                    best_word_length_val = 0;
                    updateBestWordLength(best_word_length_val);
                } else {
                    best_word_length_val = ((Long)document.get(FSBESTWORDLEN)).intValue();
                }
                word_length_val = ((Long) Objects.requireNonNull(document.get(FSWORDLEN))).intValue();
                order_important_val = (boolean) document.get(FSORDER);
                if (document.get(FSSOUNDS) == null) {
                    play_sounds_val = true;
                    updatePlaySounds(play_sounds_val);
                } else {
                    play_sounds_val = (boolean) document.get(FSSOUNDS);
                }
                uname = (String) document.get(FSUSERNAME);
                button_continue.setEnabled(true);
                // If the user name hasn't been set, show the prompt and don't let the user
                // go to the next page until they've entered one.
                if (uname == null || uname.length() == 0) {
                    no_screen_name = true;
                    screen_name_prompt.setVisibility(View.VISIBLE);
                    screen_name_fld.setVisibility(View.VISIBLE);
                } else {
                    no_screen_name = false;
                    screen_name_prompt.setVisibility(View.INVISIBLE);
                    screen_name_fld.setVisibility(View.INVISIBLE);
                }
                savePrefs(myScore, level_val, best_level_val, num_words_val, best_num_words_val, word_length_val, best_word_length_val, order_important_val, play_sounds_val, androidID, uname);
                spinner.setVisibility(View.INVISIBLE);
            } else {
                createUserDocument();
            }
        } else {
            Log.e(TAG, "getSettings() error" + task.getException());
            Toast.makeText(context, "getSettings() error" + task.getException(), Toast.LENGTH_LONG).show();
            crashlytics.log(Objects.requireNonNull(Objects.requireNonNull(task.getException()).getMessage()));
            level_val = sharedPref.getInt(FSLEVEL, 0);
            num_words_val = sharedPref.getInt(FSNUMWORDS, 0);
            word_length_val = sharedPref.getInt(FSWORDLEN, 0);
            order_important_val = sharedPref.getBoolean(FSORDER, false);
            play_sounds_val = sharedPref.getBoolean(FSSOUNDS, true);
            spinner.setVisibility(View.INVISIBLE);
        }
    }
});
}
解决方案

1. 补全用户文档初始化逻辑

核心问题大概率是createUserDocument()创建新用户文档时,未初始化FSBESTLEVEL、FSBESTNUMWORDS、FSBESTWORDLEN、FSSOUNDS这些字段。调试时你可能已有包含这些字段的测试文档,所以读取正常;但Google Play新用户首次启动时,文档是全新创建的,缺少字段导致get()返回null。

修改createUserDocument(),添加默认值初始化:

Map<String, Object> userData = new HashMap<>();
userData.put(FSBESTLEVEL, 0);
userData.put(FSBESTNUMWORDS, 0);
userData.put(FSBESTWORDLEN, 0);
userData.put(FSSOUNDS, true);
// 其他必要字段初始化...
mDevIDDocRef.set(userData);

2. 强制从服务器拉取数据

当前代码注释掉了Source.SERVER参数,默认会优先读取本地缓存(若存在)。恢复该参数可避免潜在的缓存同步问题,确保每次都从服务器获取最新文档:

mDevIDDocRef.get(Source.SERVER).addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {

3. 优化字段读取的健壮性

使用Firebase提供的类型安全方法读取字段,直接设置默认值,减少冗余的null判断:

best_level_val = document.getLong(FSBESTLEVEL) != null ? document.getLong(FSBESTLEVEL).intValue() : 0;
best_num_words_val = document.getLong(FSBESTNUMWORDS) != null ? document.getLong(FSBESTNUMWORDS).intValue() : 0;
best_word_length_val = document.getLong(FSBESTWORDLEN) != null ? document.getLong(FSBESTWORDLEN).intValue() : 0;
play_sounds_val = document.getBoolean(FSSOUNDS) != null ? document.getBoolean(FSSOUNDS) : true;

4. 验证Firebase安全规则

确认Firebase数据库规则允许发布版本的应用读取用户文档。调试签名和发布签名的SHA-1不同,需确保两者都添加到Firebase项目的应用设置中,避免权限拦截。

内容的提问来源于stack exchange,提问作者FractalBob

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 21:20:56