Данные загружаются из Firebase асинхронно.Вместо ожидания / блокировки во время загрузки данных приложение продолжается.А затем, когда данные доступны, он вызывает ваш обратный вызов.
Это легче всего увидеть с помощью некоторых операторов ведения журнала:
Debug.Log("Before starting to load data");
reference.Child("users").Child(userIdToCheck).GetValueAsync().ContinueWith(task=> {
Debug.Log("Data loaded");
});
Debug.Log("After starting to load data");
Когда вы запускаете этот код, он записывает в журнал:
Перед началом загрузки данных
После начала загрузки данных
Загрузка данных
Это, вероятно, не то, что вы ожидали, но объясняет отличнопочему вы не можете вернуть значение из обратного вызова: UserExists
уже завершился на этом этапе.
Это означает, что любой код, которому требуется доступ к данным из базы данных, должен иметь значение внутри блока ContinueWith
(или вызываться оттуда).
Самый простой подход - переместить код из вашего OnFriendRequestClicked
в UserExists
:
bool UserExists(string userIdToCheck) {
reference.Child("users").Child(userIdToCheck).GetValueAsync().ContinueWith(task=>
{
if(task.IsCompleted)
{
if(task.Result == null)
ShowError("User Id is invalid");
else
FriendsManager.instance.SendRequest(friendId);
)};
}
Затем вы можете вызвать эту функцию без if
после нее.
Вышеописанный подход прекрасно работает, но означает, что ваш метод UserExists
больше не может использоваться повторно в разных случаях.Чтобы снова использовать его повторно, вы можете передать свой собственный интерфейс обратного вызова в UserExists
.
Например, используя Task
:
bool UserExists(string userIdToCheck, Action<bool> callback) {
reference.Child("users").Child(userIdToCheck).GetValueAsync().ContinueWith(task=>
{
if(task.IsCompleted)
{
if(task.Result == null)
callback(false);
else
callback(true);
)};
}
И затем вызвать его:
FriendsManager.instance.UserExists(friendId, userExists => {
if(userExists)
FriendsManager.instance.SendRequest(friendId);
else
ShowError("User Id is invalid");
})