firebase / quickstart-unity

Firebase Quickstart Samples for Unity
https://firebase.google.com/games
Apache License 2.0
828 stars 428 forks source link

[Bug] #1236

Closed ryanwbass closed 2 years ago

ryanwbass commented 2 years ago

[REQUIRED] Please fill in the following fields:

[REQUIRED] Please describe the issue here:

Sometimes when I make GetValueAsync or SetValueAsync calls the result is never returned and the method hangs indefinitely.

I can perform the same operation over and over with it sometimes working and sometimes not.

I noticed this first for reads and got around it by adding timeouts and trying again until I got a result.

I have now noticed it happening with writes as well and am unsure how to address this as I would need to check the database after writing on another timeout since reads sometimes fail which just sounds too crazy.

I have console logs before and after my awaits and the log after the await is simply never called.

(Please list the full steps to reproduce the issue. Include device logs, Unity logs, and stack traces if available.)

Steps to reproduce:

Have you been able to reproduce this issue with just the Firebase Unity quickstarts (this GitHub project)? What's the issue repro rate? (eg 100%, 1/5 etc)

Happens Sometimes, but can happen with any of my calls.

What happened? How can we make the problem occur? This could be a description, log/console output, etc.

If you have a downloadable sample project that reproduces the bug you're reporting, you will likely receive a faster response on your issue.

Relevant Code:

Debug.Log("Start Add User To Group"); DataSnapshot userSnap = await DBreference.Child("users/" + User.UserId).GetValueAsync(); Debug.Log("Add User To Group: got user snap"); await DBreference.Child("group_users/" + groupId + "/" + User.UserId).SetRawJsonValueAsync( JsonUtility.ToJson(new UserBriefModel(userSnap))); Debug.Log("End Add User To Group");

// Output if SetAsync fails: // -Start Add User To Group // -Add User To Group: got user snap // or if GetAsync fails: // -Start Add User To Group

Either of these can happen to me as any Async call from firebase has a chance of hanging indefinitely on the return.

ryanwbass commented 2 years ago

After some research I have upgraded my timeout approach to something that should work for both reading and writing pretty well.

public static async Task GetValueAsync(string path, int tries = 0) { try { int timeout = 1000; var task = DBreference.Child(path).GetValueAsync(); if (await Task.WhenAny(task, Task.Delay(timeout)) == task) { Debug.Log("Tries to get value: " + tries); return task.Result; } else { return await GetValueAsync(path, tries + 1); } } catch (Exception e) { Debug.LogError($"{e} occurred!"); return null; } }

I'm slightly worried about the number of calls this could make and the billable cost that will be incurred as a result if the calls that hang are counted in the billing. The method sometimes tries 5-7 times before returning anything. However this is the best solution I have as of now and I will be using this until I can figure out how to prevent hanging calls or a better method.

paulinon commented 2 years ago

Hi @ryanwbass,

I see that you've found a solution to your issue. With Realtime Database, you only have to monitor the volume of data stored and downloaded if you're worried about billing. That being said, I'll close this issue.