I want to display a count down timer unified for all users. I choose a way to do it but i'm not sure if it is the best option.
server side:
user side:
The main issue i see with this method is that the user have unlimited read/write access to "timestamp" value. Can this be used against me to make fake calls to db thus increasing my Firebase usage (costing me money)
Is there a better way syncing all devices into a unified time in the future?
While I didn't find perfect solution, there is a way to avoid needing to write to a field each time. Firebase offers a built-in field /.info/serverTimeOffset
, which contains what Firebase thinks is the time difference between the client and server.
I'm using a class like this to convert timestamps received from the server to local timestamps to achieve a (decently) synced countdown.
public class ServerTimeSyncer {
private static final String TAG = "ServerTimeSyncer";
private DatabaseReference mServerTimeOffsetReference;
private long mServerTimeOffset;
public long convertServerTimestampToLocal(final long serverTimestamp) {
return serverTimestamp - mServerTimeOffset;
}
public void startServerTimeSync() {
if (mServerTimeOffsetReference == null) {
mServerTimeOffsetReference = FirebaseDatabase.getInstance().getReference("/.info/serverTimeOffset");
mServerTimeOffsetReference.addValueEventListener(mServerTimeOffsetListener);
}
}
public void stopServerTimeSync() {
if (mServerTimeOffsetReference != null) {
mServerTimeOffsetReference.removeEventListener(mServerTimeOffsetListener);
mServerTimeOffsetReference = null;
}
}
private final ValueEventListener mServerTimeOffsetListener = new ValueEventListener() {
@Override
public void onDataChange(final DataSnapshot snapshot) {
mServerTimeOffset = snapshot.getValue(Long.class);
Log.i(TAG, "Server time offset set to: " + mServerTimeOffset);
}
@Override
public void onCancelled(DatabaseError error) {
Log.w(TAG, "Server time sync cancelled");
}
};
}
See https://firebase.google.com/docs/database/android/offline-capabilities#clock-skew for more info.
Additional note: It seems this is only triggered when starting the connection, so after changing your device time, the app must be restarted in order to get the correct offset.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With