Hey guys, question might be a bit vague so allow me to elaborate.
I am creating a mobile game (Android) and am using a database to store data. Once the application is unfocused, I call the OnApplicationFocus Unity method to push an update to the database with new data. This works as expected, most of the time.
Sometimes, it will only push about half of the new data. I can see this in realtime, and eventually it just stops. I thought originally that this was going to be an issue with the database losing data, but when I reopen the application, all the old data from last session pushes to the database on the new runtime of the app.
The only thing I can think of that would cause this is Unity having some system that saves objects and code from the previous session, and it runs code it couldn’t complete once a new runtime is created. Does something like this exist? I cannot seem to find anything about it online. If not, what else could be causing this behavior?
I can provide more details if needed, I would need to if Unity doesn’t have some system like I am describing. Let me know what y’all know, thank you!
EDIT: I use OnApplicationFocus because OnApplicationQuit doesn’t allot enough time for the database calls to complete. When closing an app, you must unfocus it. This gives it more time to complete. Hopefully this clears up any inconsistencies.
No, Unity doesn’t have anything like that. Databases are typically designed to emphasize data integrity, so my first guess would be that this is a feature of the database you’re using. I haven’t heard of any Android system having a feature like that either, but I suppose it’s possible. If you’re using a third-party library to access the database, then it’s possible that that library has a system for doing it as well. Hope that helps.
You’re making a lot of assumptions about how unity works.
That will often lead you down the wrong path.
What exactly is your database code doing? If OnApplicationQuit is always invoked when you want it to that should of be enough to handle most cleanup.
If you’ve got heaps of data to save either write it locally and sync to the cloud the next time you start the app or write to your db periodically after major events so you don’t really have any last minute saves to do.
@Trafulgoth_1
I couldn’t find any documentation on Android’s docs or Firebase’s docs to suggest that the behaviour happening is expected or normal. I feel like this would be a feature that would be documented, especially considering the problems it can bring.
@Cameron_SM
Don’t know what assumptions I’m making by asking a question. If I was making assumptions I wouldn’t have asked, I would’ve assumed. I’ve already implemented autosaves and saves at critical points, but this doesn’t happen all the time and can’t since I am charged for read/writes, like any premium database does.
For some more information, here is a video: Unity/Firebase Issue - Album on Imgur. Note that the video is showing a specific set of steps in which I:
-Open the application and wait for it to load
-Close it very quickly so the calls don’t have time to complete
-Re-open the app, and all the missing data comes back
If I were to access the same account on another device, all the data is lost until it is opened on the original device again. If the app is reinstalled or updated on the original device, all the data is lost. Restarting the phone doesn’t cause the data to be lost, it is still pushed when the app opens after restart.
Any more ideas? I want to prevent this issue but also understand what is happening to determine the best attack plan to ensure no user data is ever lost.
@GamesOnAcid Generally you should not call any methods in OnApplicationQuit as objects are in the process of being unloaded from memory. I would recommend that you debug the game, either using Visual Studio or just placing Debug.Log statements around your db calls to capture the runtime variable values, they will show in the device logs via “adb logcat”. Also, please share the code you are using, we may be able to make recommendations. Tips for new Unity users and How To - Capturing Device Logs on Android
@JeffDUnity3D
Thank you for the useful response, however I want to make it clear as to what my goal of this post is.
I am aware that OnApplicationQuit/Focus cannot be reliable as the app is in the process of dying. This is why I save in other places during the runtime of the app. The point of this post is to understand why the data is coming back once the app is reopened which is visible in the video I attached in my last reply. Since you are a staff member, I will assume you are correct if you tell me this is Android or Firebase causing this, and I will redirect this question to an appropriate forum. If this turns out to be something Unity is doing, I can provide code samples and more details on how the database schema works and translates to Unity.
Hard to tell without more debug information. Some libraries (including Unity) will cache data calls if no network is detected, for example, like during app shutdown. And will then send them the next time the app is launched. We don’t need to see the db schema, just the client code and where/how it is being called. Firebase uses web sockets so we can’t use my favorite tool, Charles Proxy, to troubleshoot (which only captures HTTP/HTTPS calls). Otherwise you can use WireShark but it is very verbose and difficult to learn and use. The first step would be Debug.Log calls around your code, and provide the device logs.
Good find! But personally, I would like to see the current session data persisted as much as possible and not require a relaunch to see it. But I wouldn’t want to turn off the offline feature all together either, it’s handy if you lose the connection. There is the trade off of doing frequent db writes at an extra cost as was mentioned, vs possible non-synchronized data if you write the data in batches, and lose a batch and have to wait for a relaunch.
@Madgvox This is what I was looking for. I skimmed over it yesterday but since it’s main purpose is handling network related discrepancies, I didn’t think it applied in this case. It appears that the behavior it describes is exactly what is happening however, so you’ve found the culprit. Thanks for the help guys