Reputation: 2966
What I want to do
I have a small game with Unity, where I store a user score in firebase realtime database to display leaderboard later, when the user enters the game the first time, I also ask username and save it with deviceId(to identify the device). So now I want to handle the situation when the user don't have connection to internet, I want to store that data in the device and when user gains connection or enters the game again I will update data in firebase realtime database.
What is my problem
The problem here is that firebase doesn't throw any exception that there is no connection, and it just keeps trying to connect to internet until there is connection. You may suggest to check internet connection when user enters the game, but I want to handle it also in situations where the user for example will start with internet connection and lets say during the game the user will lose internet, if that happened I want to store data in the device as I mentioned above. So I need to catch the situation of no internet connection to be able to store data in the device.
What I have tried
1)
DatabaseReference connectedRef = FirebaseDatabase.DefaultInstance.GetReference(".info/connected");
connectedRef.ValueChanged += (object sender, ValueChangedEventArgs a) => {
bool isConnected = (bool)a.Snapshot.Value;
Debug.Log(isConnected);
};
doesn't fire when user loses internet connection during the game, so I'm unable to catch no internet connection exception
2)
Task timeoutTask = Task.Delay(1000);
Task firebaseConnection = await database.Child("users").GetValueAsync();
if (await Task.WhenAny(firebaseConnection, timeoutTask) == firebaseConnection) {
Debug.Log("timeout");
} else {
Debug.Log("completed");
}
I thought that putting timeout on firebase connection would be the only solution at the moment, but this doesn't work too Debug.Log("timeout");
never logs when there is no internet connection.
I've been searching a solution for this and found only those 2 answer which seemed possible to work, but no luck, I'm out of ideas and don't know how to solve this issue. Looking forward for your help, thanks.
Upvotes: 3
Views: 2591
Reputation: 3131
Edit:
The following code does work on my machine in the editor for the Unity SDK 6.15.1 and 6.13 on MacOS:
FirebaseDatabase.DefaultInstance.GetReference(".info/connected").ValueChanged += HandleConnectedChanged;
FirebaseDatabase.DefaultInstance.GetReference(".info/serverTimeOffset").ValueChanged += HandleServerTimeOffsetChanged;
private void HandleServerTimeOffsetChanged(object sender, ValueChangedEventArgs e)
{
Debug.Log($"Offset: {e.Snapshot.Value}");
}
private void HandleConnectedChanged(object sender, ValueChangedEventArgs e)
{
Debug.Log($"Connected: {e.Snapshot.Value}");
}
Although it may take some time to enter a "no connection" state (it won't trigger immediately when you turn off WiFi for instance) but does respond immediately to GoOffline()
and GoOnline
.
To sum up the comments:
".info/connected"
is implemented in the iOS and Android SDKs, and therefore available on device. When testing in the Unity Editor, a reimplementation of the platform specific backend SDKs written in C++ is used instead which does not have special nodes such as ".info/connected"
fully implemented (as of 6.15.1). To test logic related to the current connected state of Realtime Database, you will have to deploy to a physical device.
Additionally, try to design your game in a way that can rely mostly on ValueChanged
to read data and RunTransaction
to write data. This will give you resilience across various networking conditions and help harden your game against race conditions, and these will work in the Unity Editor if you need them for quick testing purposes.
Upvotes: 4