I would like to know how to use Firebase\'s ServerValue.TIMESTAMP method, when I want to create a timestamp at the Firebase server, and then retrieve it to the local client.
I know this question already been answered, but I wanted to share my version of the solution.
When I use the server's timestamp, i usually need to use it more than once, i.e I have some kind of startTime
and endTime
which both depend on the server's time, where startTime
is NOW
and endTime
is X seconds / minutes / hours after startTime
, so to spare the multiple requests to the server I save the server's time in a root child called serverTime
in the database, and I use it to set all dependent values.
Another thing, because of the way Firebase works with the ServerValue.Timestamp
, eventually it fires 2 events (added and changed), the first one with local timestamp and the second with the actual server's timestamp. So to overcome the issue of not receiving the correct time I added a simple OnCompleteListener
.
A short example code:
import android.support.annotation.NonNull;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.ServerValue;
import com.google.firebase.database.ValueEventListener;
public class ServerTime {
public interface OnTimeRetrievedListener {
void onTimeRetrieved(Long timestamp);
}
private final DatabaseReference db;
public ServerTime(DatabaseReference db) {
this.db = db.child("serverTime");
}
/**
* Gets the server's timestamp in milliseconds.
* @param listener {@link OnTimeRetrievedListener}
*/
public void getTime(final OnTimeRetrievedListener listener) {
if (listener == null) {
return;
}
db.setValue(ServerValue.TIMESTAMP).addOnCompleteListener(new OnCompleteListener() {
@Override
public void onComplete(@NonNull Task task) {
db.addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
listener.onTimeRetrieved(dataSnapshot.getValue(Long.class));
}
@Override
public void onCancelled(DatabaseError databaseError) { }
});
}
});
}
}