Get server time in Android
As Mobile app developers, At some point of time, we may deal with time calculation for calculating the time intervals or sending the time stamp in request to the backend, etc….
In Android, there is a possibility to alter the device time.
In such a case, when we request the device time we would get an invalid time from the device. This may lead to bugs in our app.
For example, let’s take a very popular Indian food delivery app called Swiggy. The restaurants delivering would have a closing time and the user should be restricted from placing an order after any such time. Let’s say, we are using the System time to check whether the restaurant is closed or not and the user has changes his/her mobile time then they can actually place an order which could be a major flaw in the functioning of the app.
To avoid such a flaw we should try not to use the System time that we get from the device. Instead, we should fetch the current time from any trusted server which follows the common time.
In this blog, I will be showing how we can fetch the server time from Firebase. This is a very efficient and trusted way of getting the current time.
Firstly, we have to integrate our app with Firebase by following this documentation.
After the integration, add the following dependency to get access to the Firebase DB :
implementation ‘com.google.firebase:firebase-database:19.6.0’
After adding this dependency, we should be able to access the FirebaseDatabase class.
Add the following code to get the server time offset :
fun getServerTime() {
var serverOffset: Long
FirebaseDatabase.getInstance().goOffline()
FirebaseDatabase.getInstance().goOnline()
val ref = FirebaseDatabase.getInstance().getReference(".info/serverTimeOffset")
ref.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onCancelled(error: DatabaseError) {
}
override fun onDataChange(snapshot: DataSnapshot) {
if (snapshot != null) {
serverOffset = (snapshot.value as Long).toLong()
}
}
})
}
Using this function, we will get the server offset which is the difference between device time and server time.
Now to get the real-time we need to add this offset to the current system(device) time.
val serverTime = (Date().time + serverOffset)
This function should be called at the start of our app and use the server offset wherever needed in the app.
In this way, we can get the real-time that cannot be updated by the user.
Now, there’s another case that we would need to handle if the user changes the time when the app is in the background without being killed.
For this, we need to add a broadcast receiver in our Application class to check whether the device time has changed or not like so :
val intentFilter = IntentFilter()
intentFilter.addAction(Intent.ACTION_TIME_CHANGED)
registerReceiver(timeChangedBroadcastReceiver, intentFilter)
Now if the local time is changed, the broadcast receiver would get a callback informing the device time has been changed. At this point, we can call the getServerTime() function so that we get the new offset and this offset can be used in the app.
That’s it. It’s this simple to make sure we avoid major issues with Time related functionalities.