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

Firestore字段求和时应用闪退 提示Wertung字段非Number类型

问题原因
  • 崩溃核心原因:你在Firestore中存储的Wertung字段是字符串类型,而getLong()、getDouble()方法只能读取Number类型的字段,类型不匹配就会抛出你看到的Field 'Wertung' is not a java.lang.Number异常,和你用long还是double类型接收无关。
  • 额外逻辑错误:你的查询条件写错了字段名,当前写的是筛选Bewertung字段,实际存储评分的字段是Wertung;另外就算字段名改对,对字符串类型字段做大小比较是按字典序而非数值序判断,比如字符串"10.0"会被判定为小于"2.0",完全无法得到正确的数值筛选结果。
修复方法

临时兼容方案(无需修改现有存量数据)

如果暂时没法修改Firestore中已存储的字符串格式评分,就先读取字符串值,在本地转换为数值类型后再做计算和过滤。注意字符串类型字段无法在Firestore端正确执行数值范围查询,需要全量拉取数据后在本地做过滤。
修复后的代码如下:

FirebaseFirestore rootRef = FirebaseFirestore.getInstance();
CollectionReference userExercisesRef = rootRef.collection("Nicks");
DocumentReference DocRef = userExercisesRef.document("User");
CollectionReference ColRef = DocRef.collection("Wertung");

// 字符串类型字段无法正确做数值范围查询,先全量拉取
ColRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
    @Override
    public void onComplete(@NonNull Task<QuerySnapshot> task) {
        if (task.isSuccessful()) {
            double totalScore = 0.0;
            int validNum = 0;
            for (QueryDocumentSnapshot document : task.getResult()) {
                String scoreStr = document.getString("Wertung");
                if (scoreStr == null) continue;
                try {
                    double score = Double.parseDouble(scoreStr);
                    // 本地筛选>=0.5的有效评分
                    if (score >= 0.5) {
                        totalScore += score;
                        validNum++;
                    }
                } catch (NumberFormatException e) {
                    // 跳过格式非法的评分数据,避免崩溃
                    Log.e("TAG", "评分格式错误:" + scoreStr, e);
                }
            }
            // 计算平均分,无有效评分时返回0
            double averageScore = validNum == 0 ? 0 : totalScore / validNum;
            Log.d("TAG", "总评分:" + totalScore + ",平均分:" + averageScore);
            // 将averageScore设置给RatingBar即可
        } else {
            Log.e("TAG", "查询失败", task.getException());
        }
    }
});

根源修复方案(推荐长期使用)

所有数值类字段(尤其是需要做范围筛选、数值计算的字段)必须在Firestore中存储为Number类型,不要存为字符串:

  • 后续写入评分时,直接将RatingBar返回的float/double类型评分值存入Firestore,不要转换为字符串后再写入
  • 对已存在的字符串格式存量数据,执行一次批量更新,将所有文档下的Wertung字段转换为Number类型后覆盖存储

存储格式修正后,既可以直接在Firestore端执行正确的数值范围查询,也可以直接调用getDouble()读取字段值,不会再触发类型转换异常,代码可简化为:

// 字段为Number类型时,范围查询可正常生效
Query query = ColRef.whereGreaterThanOrEqualTo("Wertung", 0.5);
query.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
    @Override
    public void onComplete(@NonNull Task<QuerySnapshot> task) {
        if (task.isSuccessful()) {
            double totalScore = 0.0;
            for (QueryDocumentSnapshot document : task.getResult()) {
                double score = document.getDouble("Wertung");
                totalScore += score;
            }
            int validNum = task.getResult().size();
            double averageScore = validNum == 0 ? 0 : totalScore / validNum;
            Log.d("TAG", "总评分:" + totalScore + ",平均分:" + averageScore);
        }
    }
});

注意:评分是0.5-5.0的浮点值,累加、计算平均值时不要用long类型存储,会丢失小数精度,导致最终RatingBar显示的评分不准确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 09:39:20