2015-12-30 11 views
9

Otrzymuję następujący wyjątek podczas aktualizowania istniejącej wartości w Firebase przy użyciu metody updateChildren.com.firebase.client.FirebaseException: Nie można przeanalizować węzła za pomocą klasy klasy CLASS_NAME android

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) 

Mój model wygląda następująco:

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 obiektu, który chcę zaktualizować wygląda jak ten na Firebase:

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

i moja metoda onDateChange wygląda następująco:

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(); 
} 
+0

Proszę podać rzeczywisty tekst JSON z bazy danych Firebase. Możesz go uzyskać, klikając przycisk Eksportuj w panelu Firebase, co pozwoli nam skopiować/wkleić JSON do testowania (lub do odpowiedzi). –

+0

@FrankvanPuffelen Dodałem tekst JSON. –

+0

Dzięki. Brakuje nam również kodu, który zapisuje do Firebase (w 'onDataChange()'). I czy klasa "HashTagModel" naprawdę jest potrzebna (i czy musi być tak duża), aby odtworzyć problem? –

Odpowiedz

14

przeciwieństwie do metody setValue(), updateChildren() nie wykonuje konwersję Java-to-JSON na wartości (ów), które przechodzą w.

Ty przepuszczanie HashMap<String, Object> do updateChildren(), który pasuje do umowy z tym API. Ale jestem pewien, że w niektórych wartościach masz obiekt Java (prawdopodobnie HashTagModel), który nie jest bezpośrednio odwzorowany na typ JSON.

Ale co można zrobić, to przekształcić POJO na mapie z:

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

Następnie można umieścić mapę wartości na wartości, że jesteś przechodzącej do updateChildren().

+0

Dzięki @FrankvanPuffelen – srinivas

+0

@FrankvanPuffelen co z tym, że jackson nie jest już używany przez FirebaseDatabase? Czy powinniśmy zaimportować go jako zależność, aby osiągnąć ten sam rezultat? Wolałbym nie, ponieważ z tego, co czytałem, jedną z przyczyn jego usunięcia była troska o ostateczny rozmiar apk. (Ref. Http://stackoverflow.com/questions/37335712/android-firebase-9-0-0-setvalue-to-serialize-enums) – Ena

+0

Jeśli okaże się, że nasza nowa serializacja/deserializacja nie działa, możesz użyć Jacksona. Aby uzyskać wskazówki, jak to zrobić, zobacz [tę odpowiedź] (http://stackoverflow.com/questions/37547399/how-to-deserialise-a-subclass-in-firebase-using-getvaluesubclass-class/37548330#37548330). I nie zapomnij również poinformować nas o tym, jak to możliwe, abyśmy mogli dodać do niego wsparcie. –

Powiązane problemy