【问题标题】:com.firebase.client.FirebaseException: Failed to parse node with class class CLASS_NAME androidcom.firebase.client.FirebaseException:无法解析具有类 CLASS_NAME android 的节点
【发布时间】:2025-12-08 13:20:07
【问题描述】:

我在使用 updateChildren 方法更新 Firebase 中的现有值时遇到以下异常。

com.firebase.client.FirebaseException: Failed to parse node with class class com.shajeelafzal.quicktasks_app.models.HashTagModel
  at com.firebase.client.snapshot.NodeUtilities.NodeFromJSON(NodeUtilities.java:84)
  at com.firebase.client.snapshot.NodeUtilities.NodeFromJSON(NodeUtilities.java:12)
  at com.firebase.client.utilities.Validation.parseAndValidateUpdate(Validation.java:127)
  at com.firebase.client.Firebase.updateChildren(Firebase.java:438)
  at com.shajeelafzal.quicktasks_app.fragments.AddEditTaskFragment$4.onDataChange(AddEditTaskFragment.java:408)

我的模型如下所示:

public class HashTagModel implements Parcelable {

    private HashMap<String, Object> timeStampLastUsed;
    @Expose
    private String name;
    @Expose
    private String createByUserEmail;
    private List<String> tasksKeys;

    public HashTagModel() {
    }

    public HashTagModel(HashMap<String, Object> timeStampLastUsed, String name,
                        String createByUserEmail, ArrayList<String> tasksKeys) {
        this.timeStampLastUsed = timeStampLastUsed;
        this.name = name;
        this.createByUserEmail = createByUserEmail;
        this.tasksKeys = tasksKeys;
    }
}

我要更新的 JSON 对象在 Firebase 上如下所示:

"hashTags" : {
    "USER_EMAIL" : {
      "USA" : {
        "createByUserEmail" : "USER_EMAIL",
        "name" : "#USA",
        "tasksKeys" : [ "-K6mS36uhKthKf1-1pF1" ],
        "timeStampLastUsed" : {
          "timestamp" : 1451514461234
        }
      }
    }
  }

而我的onDateChange 方法如下所示:

public void onDataChange(DataSnapshot dataSnapshot) {
    /** if the hash tag does not exists already then create new one. */
    if (dataSnapshot.getValue() == null) {
        HashMap<String, Object> timestampJoined = new HashMap<>();
        timestampJoined.put(Constants.FIREBASE_PROPERTY_TIMESTAMP, ServerValue.TIMESTAMP);

        ArrayList<String> keysList = new ArrayList<String>();
        keysList.add(key);

        HashTagModel hashTag = new HashTagModel(timestampJoined, "#" + mHashTags.get(finalI),
                Utils.decodeEmail(mEncodedEmail), keysList);
        finalHashTagLocation.setValue(hashTag);
    } else {

        HashTagModel hashtaghModel = dataSnapshot.getValue(HashTagModel.class);

        hashtaghModel.getTasksKeys().add(key);

        /* HashMap for data to update */
        HashMap<String, Object> updateUserTaskData = new HashMap<>();


        Utils.updateMapForAllWithValue(null, mHashTags.get(finalI), mEncodedEmail,
                updateUserTaskData, "", hashtaghModel, Constants.FIREBASE_LOCATION_USER_HASH_TAGS);


        /** update the Hash Tag */
        finalHashTagLocation.updateChildren(updateUserTaskData, new Firebase.CompletionListener() {
            @Override
            public void onComplete(FirebaseError firebaseError, Firebase firebase) {
                Log.i("", "");
            }
        });
    }

    getActivity().finish();
}

【问题讨论】:

  • 请包含您 Firebase 数据库中的实际 JSON 文本。您可以通过单击 Firebase 仪表板中的“导出”按钮来获取它,它允许我们复制/粘贴 JSON 以进行测试(或粘贴到答案中)。
  • @FrankvanPuffelen 我添加了 JSON 文本。
  • 谢谢。我们还缺少写入 Firebase 的代码(在 onDataChange() 中)。并且真的需要 HashTagModel 类(并且需要这么大)来重现问题吗?
  • @FrankvanPuffelen 我可以删除 Parcelable 代码。我想我可能有助于理解。我正在添加应该更新的代码。
  • 我很确定您会受到与此处所述相同的问题的影响:*.com/questions/32848024/…。您不能将 Java 类传递给 updateChildren()。我对这个问题的回答有一个解决方法。

标签: android firebase firebase-realtime-database


【解决方案1】:

setValue() 方法不同,updateChildren() 不会对您传入的值执行 Java 到 JSON 的转换。

您将HashMap&lt;String, Object&gt; 传递给updateChildren(),这符合该API 的合同。但我很确定在某些值中,您有一个未直接映射到 JSON 类型的 Java 对象(可能是HashTagModel)。

但你可以做的是将 POJO 转换为 Map :

Map<String, Object> hashtaghMap = new ObjectMapper().convertValue(hashtaghModel, Map.class);

然后您可以将值映射到您传递给updateChildren() 的值中。

【讨论】:

  • 谢谢@FrankvanPuffelen
  • @FrankvanPuffelen 现在 FirebaseDatabase 不再使用杰克逊了?我们应该将它作为依赖项导入以达到相同的结果吗?我宁愿不这样做,因为从我读到的删除它的原因之一是担心最终的 apk 大小。 (参考*.com/questions/37335712/…
  • 如果您发现我们的新序列化/反序列化无法处理的需求,您可以使用 Jackson。请参阅this answer 了解如何执行此操作。并且不要忘记让我们知道您的用例,以便我们考虑增加对它的支持。
  • @FrankvanPuffelen 感谢您的快速回复。我的用例与这个答案完全相同:使用 updateChildren 而无需手动将 pojo 转换为地图。您建议使用 ObjectMapper 但它是 Jackson 类,所以我想知道我们是否可以使用 FirebaseDatabase API 实现相同的结果。我错过了什么吗? (请原谅我的无知,为什么updateChidren不像setValue那样允许pojos?如果有一个允许pojos的相应方法是可行的,我会要求支持它:))
  • @FrankvanPuffelen 我也从上面支持@Ena 的问题。有什么方法可以使用updateChildren而不需要手动将对象转换为地图?