1

I know this is old and i can find some popular post about this here. but i swear i am still stuck, i don't really understand every answer posted, it's been 7 hours, please be kind and provide me answer, this is killing me.

to make the answer is clear and direct, i decided to post one answer from other post that i think might be the answer, but i just don't know how to apply it to my code.

So, i use POJO :

HashMap<String, Object> timestamp = new HashMap<>();

public Reservation(String rid,Map timestamp, String status) {
    this.rId = rid;
    this.timestamp = timestamp;
    this.status = status;
}

 public Map getTimestamp() {
   return timestamp;
 }

and this is how i write to db :

 private void SendReservation() {
    final String key = mDatabaseRes.child("Reservations").push().getKey();

    final Reservation reservation = new Reservation(MainActivity.currUser.getUID(),ServerValue.TIMESTAMP,"pending");         

    mDatabaseRes.child("Reservations").child(key).setValue(reservation, new DatabaseReference.CompletionListener() {
        @Override
        public void onComplete(DatabaseError databaseError, DatabaseReference reference) {
            if (databaseError != null) {

                Log.e("Database ERROR", "Failed to write message", databaseError.toException());
            } else {
                Toast.makeText(getApplicationContext(),
                        "success"
                        , Toast.LENGTH_LONG).show();
            }
        }
    });


}

until now i successfully write to db, the timestamp also display the time 14090282xxxx (seems correct until now), the error raised when reading the timestamp value, something like "cannot deserialize the long to map" at the snapshot get value :

reservationList.clear();
for (DataSnapshot dsp : dataSnapshot.getChildren()) {
    reservationList.add(dsp.getValue(Reservation.class)); //add result into array list

}

Okay, as i said, let me pick and show one answer here from kevin o'neill, how can i apply to mine : here is the link

Param param1;
Param param2;
HashMap<String, Object> timestampCreated;

//required empty constructor
public DataObject(){}

    public DataObject(Param param1, Param param2) {
           this.param1 = param1;
           this.param2 = param2;
           HashMap<String, Object> timestampNow = new HashMap<>();
           timestampNow.put("timestamp", ServerValue.TIMESTAMP);
    }
    public HashMap<String, Object> getTimestampCreated(){
       return timestampCreated;
    }

    @Exclude
    public long getTimestampCreatedLong(){
       return (long)timestampCreated.get("timestamp");
    }

this is accepted answer with some votes , what confuse me is what is the connection between timestamnow and timestampcreated ? , also the constructor doesn't have timestamp like the one i have.

what i need to add to my code to make it get the right result.

Community
  • 1
  • 1
Goofy_Phie
  • 671
  • 1
  • 8
  • 25
  • check this https://stackoverflow.com/questions/45203371/i-want-the-value-of-timestamp-in-long-format-iam-using-servervalue-timestamp/46787256#46787256 – ahmed khattab Oct 17 '17 at 09:52

5 Answers5

4

after stuck for 14 hours, i finally came up with solution.

i inspired from here

Since the source don't have any explanation, i will rewrite it here according to my case with some explanation.

First i remove all my serverValue.timeStamp outside my class, i also remove it from my constructor.

then i add this variable member Long creationDate;

and add the public getter so it can write the timestamp to the DB:

 public java.util.Map<String, String> getCreationDate() {
    return ServerValue.TIMESTAMP;
}

last thing to do is to add the method to retrieve the value as long

@Exclude
public Long getCreationDateLong() {
    return creationDate;
}

That's it, I tested it and worked, i hope it can help someone later too.

Community
  • 1
  • 1
Goofy_Phie
  • 671
  • 1
  • 8
  • 25
1

The ideea is that when you set the TIMESTAMP in your database, you set it as a map and when you retrieve it, you retrieve it as a Long.

So in order to get the correct TIMESTAMP you need to put a listener on the correct location and than extract the TIMESTAMP from the dataSnapshot like this:

Long timeStampLong = (Long) dataSnapshot.child("timestamp").getValue();

Than you need to use a method to convert it like this:

public static String getTimeDate(long timeStamp){
    try{
        DateFormat dateFormat = getDateTimeInstance();
        Date netDate = (new Date(timeStamp));
        return dateFormat.format(netDate);
    } catch(Exception e) {
        return "date";
    }
}

If you want to get the TIMESTAMP from the object than you need to use in your model, public setters and public getters like this:

public void setTimeStamp(Map<String, String> timeStamp) {
    this.timeStamp = timeStamp;
}
public Map<String, String> getTimeStamp() {
    return timeStamp;
}

Hope it helps.

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • but how if i want to retrieve it in my object in one snapshot get value like mine above? i mean i want the value through a getter – Goofy_Phie Apr 26 '17 at 16:15
  • Please see the updated answer. And don't forget to set the `TIMESTAMP` as a `Map`, not as a `HashMap`. – Alex Mamo Apr 26 '17 at 16:22
  • i think i already used the same getter like you write here (please check my pojo model above) the getter in map type and that caused the error. that's why i quoted kevin oneil answer bcause i saw he used long getter, but somehow i don't know how to apply the same to my code. – Goofy_Phie Apr 26 '17 at 16:28
  • You did not! Change `HashMap timestamp = new HashMap<>();` with `Map timestamp;` You don't need to create a new object inside your pojo. You will create a new object only when you will use the `setter` method or the right constructor. The getter inside your pojo is also wrong. The return type needs to be `Map` not only `Map`. In constructor the change `Map timestamp` with `Map timestamp`. – Alex Mamo Apr 26 '17 at 16:41
  • sir, i just changed my code like you suggested, but same error still occured. – Goofy_Phie Apr 27 '17 at 02:14
  • When you try to add those values to the `list`, you are adding different types of elements. You need to use `addListenerForSingleValueEvent` on field `timestamp`, a retrieve it as: `Long timeStampLong = (Long) dataSnapshot.child("timestamp").getValue();` It should work for sure. – Alex Mamo Apr 27 '17 at 05:31
  • 1
    i apologize sir, but i really want to do it in POJO's way. i believe separate reading like that might be work , but unfortunately that's not what i wanted. – Goofy_Phie Apr 27 '17 at 06:20
  • Biut this is what we are trying to do, to use public setters and getters in your pojo to set and get the timestamp in a correct way. – Alex Mamo Apr 27 '17 at 09:09
  • do you mean that it's impossible to get the timestamp by using code like `for (DataSnapshot dsp : dataSnapshot.getChildren()) { reservationList.add(dsp.getValue(Reservation.class)); `? – Goofy_Phie Apr 27 '17 at 09:19
  • When you are using 'getChildren ()' method in your dataSnapShot exists Sting objects and Long objects. So you need to listen for a single child, timestamp. – Alex Mamo Apr 27 '17 at 09:21
  • why can't i treat the timestamp the same as other variable in my class e.g : id and status, which can be written and read by setValue and getValue by class (constructor) ? why i need to get the timestamp in separated way (i mean,listen to specific children). i hope you understand what i am trying to achieve here. thankyou – Goofy_Phie Apr 27 '17 at 09:43
  • To get the data from the object you need to use something like this: Reservation reservation = dataSnapShot.getValue (Reservation.class); and than Long timestamp = reservation.getTimeStam (); – Alex Mamo Apr 27 '17 at 09:49
  • that won't work sir. i've tried it. i still get that cannot deserialize error. error already caught in that datasnapshot.getvalue(reservation.class), that reservation.getTimestamp() not even have chance to be executed. – Goofy_Phie Apr 27 '17 at 09:59
  • How do you do that in kotlin? – Dr4ke the b4dass Dec 11 '19 at 01:37
  • @Dr4ketheb4dass For Kotlin, check my new answer. – Alex Mamo Dec 11 '19 at 06:47
1

For Kotlin users, the idea is the same. When you set the TIMESTAMP, you set it as a Map and when you retrieve it, you retrieve it as a long.

So in order to get the correct TIMESTAMP you need to attach a listener on the correct location and than extract the TIMESTAMP from the dataSnapshot like this:

val timestamp = dataSnapshot.child("timestamp").getValue() as Long

Then you need to use a method to convert it like this:

fun getTimeDate(timeStamp: Long): String? {
    return try {
        val dateFormat: DateFormat = getDateTimeInstance()
        val netDate = Date(timeStamp)
        dateFormat.format(netDate)
    } catch (e: Exception) {
        e.message
    }
}

If you want to get the TIMESTAMP from the object than you need to use in your model, a timestamp field like this:

val timestamp = emptyMap<String, String>()
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
0

By far the easiest if you ask me.

long serverTime = Timestamp.now().getSeconds();

Can be used anywhere and everywhere.

0

I used Object type for date(timeStamp) field in model class. This is enough.

public class Post {
    private String message;
    private Object timeStamp; //<<<<<<<<<<<<<<<<<<<<< Object 

    public Post() {
    }

    public Post(String message, Object timeStamp) {
        this.message = message;
        this.timeStamp = timeStamp;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getTimeStamp() {
        return timeStamp;
    }

    public void setTimeStamp(Object timeStamp) {
        this.timeStamp = timeStamp;
    }
}

When writing to Firebase:

FirebaseDatabase db = FirebaseDatabase.getInstance();
DatabaseReference ref = db.getReference("Posts");

Post newPost = new Post("merhaba", ServerValue.TIMESTAMP);
ref.push().setValue(newPost);

When reading data from Firebase :

FirebaseDatabase db = FirebaseDatabase.getInstance();
DatabaseReference ref = db.getReference("Posts");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        postArrayList.clear();
        for (DataSnapshot data : dataSnapshot.getChildren()){
            Post m = data.getValue(Post.class);
            postArrayList.add(m);
        }
        adapterPost.notifyDataSetChanged();
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {

    }
});

When reading timeStampValue :

Post post = postArrayList.get(position);
String timeStampValue= new SimpleDateFormat("MM/dd/yyyy").format(new Date((long) post.getTimeStamp()));