1

I'm trying to update a Firebase Object from Android. One of the field is a Date.

Something as simple as:

Map<String, Object> fields = new HashMap<String, Object>();

fields.put("endDate", new Date());
.... some more fields ....

firebaseRef.updateChildren(fields);

crashes with

Caused by: com.firebase.client.FirebaseException: Failed to parse node with class class java.util.Date
                                                              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.firebase.client.Firebase.updateChildren(Firebase.java:426)
                                                              at com.mw.mydot.application.MyApp.updateRideOnPayment(MyApp.java:353)
                                                              at com.mw.mydot.FareSummaryActivity.onPaymentReceived(FareSummaryActivity.java:180)
                                                              at java.lang.reflect.Method.invokeNative(Native Method) 
                                                              at java.lang.reflect.Method.invoke(Method.java:515) 
                                                              at android.support.v7.internal.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:273) 
                                                              at android.view.View.performClick(View.java:4456) 
                                                              at android.view.View$PerformClick.run(View.java:18465) 
                                                              at android.os.Handler.handleCallback(Handler.java:733) 
                                                              at android.os.Handler.dispatchMessage(Handler.java:95) 
                                                              at android.os.Looper.loop(Looper.java:136) 
                                                              at android.app.ActivityThread.main(ActivityThread.java:5086) 
                                                              at java.lang.reflect.Method.invokeNative(Native Method) 
                                                              at java.lang.reflect.Method.invoke(Method.java:515) 
                                                              at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) 
                                                              at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601) 
                                                              at dalvik.system.NativeStart.main(Native Method) 

When I comment this line with Date field, all the other fields are updated normally.

NOTE: 'endDate' field is a new field that I'm trying to add to an existing object.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Pranav Mahajan
  • 2,048
  • 2
  • 23
  • 36

1 Answers1

6

Firebase stores JSON data. There is no native type for representing a date in JSON.

Developers typically pick one of these representations for their dates:

  1. numeric timestamps
  2. strings

Storing timestamps (number of seconds/milliseconds since January 1, 1970) has the advantage that they are numbers and thus can be easily compared.

Storing dates as strings has the advantage that they can be easily displayed, without first having to convert them.

If you need to both properties, you could also store the relevant date/time in both formats: as a timestamp and as a string.

Map<String, Object> fields = new HashMap<String, Object>();

fields.put("endDate_timestamp", new Date().getTime());
fields.put("endDate_string", new Date().toString());

ref.updateChildren(fields);

If you're doing the above, you consider letting the Firebase server determine the timestamp:

fields.put("endDate_server_timestamp", ServerValue.TIMESTAMP);

This ensures that the timestamp matches the exact moment the value is written on the server.

Related:

Community
  • 1
  • 1
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • Then how come there is no problem while creating objects : firebaseRef.setValue( new MyOwnClass( new Date() , null, new Date()) ); works fine & saves the Date. – Pranav Mahajan Dec 31 '15 at 05:14
  • While creating an object firebase itself converts Date to Time. It's not unfair to expect it to do the same while updating. – Pranav Mahajan Dec 31 '15 at 05:33
  • The code path is different between `setValue()` and `updateChildren()`. The former does more conversions than the latter, which doesn't allow any non-JSON types. See http://stackoverflow.com/questions/32848024/android-firebase-2-4-illegalstateexception-using-new-ref-updatechildren for a bit more on this (and a possible other workaround). – Frank van Puffelen Dec 31 '15 at 05:47