Search code examples
javaandroidfirebase-realtime-databasecountdowntimer

Start a countdown on several connected devices at the same time - Firebase Android


I'm creating an Android application, in which players are connected to Firebase Realtime Database (2 to 4 players per room). If I summarize what my code should do: players can click on a button each in turn. When a player clicks and it's his turn, the app will write (with runTransaction) on the server an int type (for example "clicked:2" means that player 2 just clicked). When the "clicked" key is visible on the server (with addValueEventListener), all players connected to this room perform (at the same time and the execution is done on the client side) a 3 seconds CountDownTimer. During this countdown, all players (without exception) can click on their buttons, and if this is the case only the first one to click will be taken into account (because runTransaction) and will be written on the server. So everyone will see on his device that a player has clicked on his button during the countdown, and then we start all over again (i.e. it's up to the next player to start the countdown etc). Theoretically, this is fine, but a problem arise after testing (with an old and a new - and therefore faster - smartphone):

Some devices are faster than others, and in most cases the countdown doesn't start at the same time for different players. So I was thinking, for example (but others are possible, don't hesitate to say so !), to write on the server at what time (in ms) the player clicked, and take this time + 500 ms (or other) to start the countdown. But for that you would need to have Firebase time (TimeStamp I think) and I don't know how... (preferably only in Java, I don't like to touch json too much)


Solution

  • One of the factors affecting the client-side countdown timers is going to be the latency between each client and the server. A client with a faster connection will get the updated value sooner, and hence start the countdown timer sooner.

    Firebase estimates this latency when the client first connects, and makes it available in the .info/serverTimeOffset node in the client. You can use this value to (partially) correct for the latency. For more on this, and sample code, see the documentation on clock skew.