Skip to content

[Bug] Windows Crashes after exactly 1 hour when signed in to Firebase #540

Open
@megavoid

Description

@megavoid

[REQUIRED] Please fill in the following fields:

  • Unity editor version: 2021.3.12f1
  • Firebase Unity SDK version: 8.8.0 (and still in 10.1.0)
  • Source you installed the SDK: .unitypackage
  • Problematic Firebase Component: Database, maybe in interplay with Auth
  • Other Firebase Components in use: only Auth & Database
  • Additional SDKs you are using: none
  • Platform you are using the Unity editor on: Mac & Windows
  • Platform you are targeting: Mac & Windows desktop
  • Scripting Runtime: IL2CPP, same behaviour in Mono though
  • Pre-built SDK from the website or open-source from this repo: pre-built from website

[REQUIRED] Please describe the issue here:

On Windows our software crashes exactly 1 hour after signing in to Firebase. This happens about 90% of the time on several test machines with the compiled App (both IL2CPP and Mono) and both with username/password login and resume session by token. Running content / scenes do not matter, it even crashes only being idle in main menu.

It also crashes the Unity editor, though it seems to happen less often than the compiled App, about 70% of the time.

The App runs totally fine being signed out (login screen at start) and also does not crash when there is no internet connection available (cable pulled, wifi deactivated) at the usual crash point after 1 hour runtime.

The Mac version is completely stable.

What I did try

As the crash timing is so exact, my first thought was that it is related to the ID token expiring. Thus I added code to manually refresh the ID token every 15 minutes. This did not fix the issue.
As the only other thing we do on Firebase right now is getting some data from the Realtime Database after login we also tried the workaround from this issue -> firebase/quickstart-unity#1284 disabling Persistence. This also did not fix our crashes.

Steps to reproduce:

Have you been able to reproduce this issue with just the Firebase Unity quickstarts (this GitHub project)?
No, quickstarts has compiler errors in Unity 2021.3

What's the issue repro rate? (eg 100%, 1/5 etc)
90% compiled, 70% editor

What happened? How can we make the problem occur?
Download our software from https://get.infinite-realms.de/2022/Setup_IR-2022.0.5.exe - install - sign up & in - wait 1 hour

Relevant Code:

Stack Trace v8.8.0:

0x00007FFB96235440 (FirebaseCppApp-8_8_0) Firebase_App_CSharp_InitializePlayServicesInternal
0x00007FFB96252E76 (FirebaseCppApp-8_8_0) SWIGRegisterStringCallback_FirebaseAnalytics
0x00007FFB96428256 (FirebaseCppApp-8_8_0) SWIGRegisterStringCallback_StorageInternal
0x00007FFB96436E46 (FirebaseCppApp-8_8_0) SWIGRegisterStringCallback_StorageInternal
0x00007FFB9642B13C (FirebaseCppApp-8_8_0) SWIGRegisterStringCallback_StorageInternal
0x00007FFB96430CDC (FirebaseCppApp-8_8_0) SWIGRegisterStringCallback_StorageInternal
0x00007FFB96399991 (FirebaseCppApp-8_8_0) SWIGRegisterStringCallback_StorageInternal
0x00007FFB9639ADFA (FirebaseCppApp-8_8_0) SWIGRegisterStringCallback_StorageInternal
0x00007FFB96439082 (FirebaseCppApp-8_8_0) SWIGRegisterStringCallback_StorageInternal
0x00007FFB96437A05 (FirebaseCppApp-8_8_0) SWIGRegisterStringCallback_StorageInternal
0x00007FFB96438B14 (FirebaseCppApp-8_8_0) SWIGRegisterStringCallback_StorageInternal
0x00007FFB96568801 (FirebaseCppApp-8_8_0) SWIGRegisterStringCallback_StorageInternal
0x00007FFB96569E0A (FirebaseCppApp-8_8_0) SWIGRegisterStringCallback_StorageInternal
0x00007FFB96312BAF (FirebaseCppApp-8_8_0) SWIGRegisterStringCallback_StorageInternal
0x00007FFB962BFB28 (FirebaseCppApp-8_8_0) SWIGRegisterStringCallback_StorageInternal
0x00007FFB9673CC8D (FirebaseCppApp-8_8_0) SWIGRegisterStringCallback_StorageInternal
0x00007FFBEFE9244D (KERNEL32) BaseThreadInitThunk
0x00007FFBF094DFB8 (ntdll) RtlUserThreadStart

Weirdly FirebaseAnalytics shows up in the trace, although the module is not installed. We did try to install FirebaseAnalytics SDK afterwards because we thought maybe a call to the absent module caused the crash. This also did not fix the issue.

Stack Trace v10.1.0

PDB: 'C:\WINDOWS\system32\ncryptsslp.dll', fileVersion: 10.0.22621.1
  ERROR: SymGetSymFromAddr64, GetLastError: 'Es wurde versucht, auf eine unzulässige Adresse zuzugreifen.' (Address: 00007FFE15B38AEB)
0x00007FFE15B38AEB (FirebaseCppApp-10_1_0) (function-name not available)
0x00007FFE15C231F8 (FirebaseCppApp-10_1_0) uS::Node::getLoop
0x00007FFE15C3014D (FirebaseCppApp-10_1_0) uS::Node::getLoop
0x00007FFE15C24707 (FirebaseCppApp-10_1_0) uS::Node::getLoop
0x00007FFE15C289F5 (FirebaseCppApp-10_1_0) uS::Node::getLoop
0x00007FFE15C07828 (FirebaseCppApp-10_1_0) uS::Node::getLoop
0x00007FFE15C08B7A (FirebaseCppApp-10_1_0) uS::Node::getLoop
0x00007FFE15C323A0 (FirebaseCppApp-10_1_0) uS::Node::getLoop
0x00007FFE15C30D6A (FirebaseCppApp-10_1_0) uS::Node::getLoop
0x00007FFE15C31EBA (FirebaseCppApp-10_1_0) uS::Node::getLoop
0x00007FFE15C451BC (FirebaseCppApp-10_1_0) uS::Socket::write
0x00007FFE15C46EF3 (FirebaseCppApp-10_1_0) uWS::WebSocketState<0>::operator=
0x00007FFE15BA2964 (FirebaseCppApp-10_1_0) uS::Socket::freeMessage
0x00007FFE15BABEFF (FirebaseCppApp-10_1_0) uS::Socket::freeMessage
0x00007FFE85549363 (ucrtbase) recalloc
0x00007FFE874F244D (KERNEL32) BaseThreadInitThunk
0x00007FFE8814DFB8 (ntdll) RtlUserThreadStart

Login routines:

private IEnumerator Login(string email, string password)
        {
            var loginTask = Auth.SignInWithEmailAndPasswordAsync(email, password);

            yield return new WaitUntil(predicate: () => loginTask.IsCompleted);

            if (loginTask.Exception != null)
            {
                Debug.LogWarning(message: $"Failed to register task with {loginTask.Exception}");
            }
            else
            {
                User = loginTask.Result;

                if (User.IsEmailVerified)
                {
                    OnUserSignedIn?.Invoke();
                }
                else
                {
                    OpenVerificationMailPopup();
                }
            }
        }

private void TryResumeSession()
        {
            if (Auth.CurrentUser != null)
            {
                User = Auth.CurrentUser;

                if (User.IsEmailVerified)
                {
                    OnUserSignedIn?.Invoke();
                }
                else
                {
                    Logout();
                }
            }
        }

Realtime Database call example. We only do these after login. When offline and signed in via token the App loads settings from cache file instead of database:

        private IEnumerator LoadSettings()
        {
            // Abwarten bis der User eingelogged ist, vorher hat er keine Rechte auf der Datenbank
            yield return new WaitUntil(predicate: () => IsSignedIn());

            // Daten holen
            Task<DataSnapshot> databaseTask;
            var waitCount = 0;
            
            var versionName = Application.version.Replace('.', '-');
            databaseTask = DatabaseReference.Child("settings").Child(versionName).GetValueAsync();

            while (!databaseTask.IsCompleted)
            {
                if (databaseTask.Status == TaskStatus.WaitingForActivation)
                    waitCount++;
                
                // Fehler oder Timeout
                if (databaseTask.Exception != null || waitCount > 200)
                {
                    VersionSettings = ES3.Load<Dictionary<string, string>>("versionSettings", "firebase.pref");
                    SetOfflineMode();
                    break;
                }
                yield return null;
            }

            if (!OfflineMode)
            {
                // Datenbank verbunden, aktuelle Daten holen und abspeichern
                DataSnapshot snapshot = databaseTask.Result;
                VersionSettings = new Dictionary<string, string>();

                // Relevante Werte auslesen
                if (!VersionSettings.TryAdd("catalogRealms", snapshot.Child("catalog-realms").Value.ToString()))
                {
                    SetFatalError();
                    yield break;
                }
                if (!VersionSettings.TryAdd("catalogCore", snapshot.Child("catalog-core").Value.ToString()))
                {
                    SetFatalError();
                    yield break;
                }
                if (!VersionSettings.TryAdd("deprecated", snapshot.Child("deprecated").Value.ToString()))
                {
                    SetFatalError();
                    yield break;
                }
                
                // Version Settings für Offline-Modus cachen
                ES3.Save("versionSettings", VersionSettings, "firebase.pref");
            }
            
            OnSettingsLoaded?.Invoke();
        }

Attempt to fix the crash by manually refreshing ID token every 15 minutes:

        #region Token
        private void StartTokenRefreshTimer()
        {
            InvokeRepeating(nameof(TokenRefresh), 900, 900);
            OnUserSignedIn -= StartTokenRefreshTimer;
        }

        private void TokenRefresh()
        {
            Auth.CurrentUser.TokenAsync(true).ContinueWith(task => {
                if (task.IsCanceled) {
                    Debug.LogError("TokenAsync was canceled.");
                }
                else if (task.IsFaulted) {
                    Debug.LogError("TokenAsync encountered an error: " + task.Exception);
                }
            });
        }
        #endregion

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions