Асинхронная функция внутри сопрограмм не работает на Android - PullRequest
0 голосов
/ 26 марта 2019

Я пытаюсь создать поток входа через Facebook в моем проекте Unity. Я использую Facebook SDK и Firebase для аутентификации и хранения пользовательских данных в онлайн-базе данных.

Мне нужно обновлять БД только тогда, когда пользователя там нет. Поэтому я использую сопрограмму

    public void someCodeHere(params){
        StartCoroutine(waitForTask(task, uid, name, email));
}

    IEnumerator waitForTask(Task<DataSnapshot> task, string uid, string name, string email)
    {
        while(!task.IsCompleted)
        {
            Debug.Log("Wait task to coplete");
            yield return new WaitForSeconds(1);
        }
        Debug.Log(task.Result.GetRawJsonValue());
        if(task.Result.GetRawJsonValue() == null || task.Result.GetRawJsonValue() == "")
        {
            HardUpdateUser(uid, name, email);
        }
        else
        {
            SetExistingUser(task);
        }
    }

SetExistingUser отлично работает в редакторе и на устройстве, однако HardUpdateUser (uid, name, email); не работает на устройстве, но отлично работает в редакторе Unity.

вот код внутри функции:

        var status = reference.Child("users").Child(userId).SetRawJsonValueAsync(json).ContinueWith(task =>
        {

            if (task.IsCanceled)
            {
                Debug.LogError("CreateUpdateUserInDB was canceled.");
                return;
            }
            if (task.IsFaulted)
            {
                Debug.LogError("CreateUpdateUserInDB encountered an error: " + task.Exception);
                return;
            }
            Debug.LogFormat("User CreateUpdateUserInDB successfully: {0} ({1})",
                user.userName, userId);

        });

1 Ответ

0 голосов
/ 28 марта 2019

Итак.Я не получил журналы, потому что у меня не хватает времени, и я думаю, что я был ленивым.В любом случае я нахожу обходной путь для моей проблемы.

То, о чем я не упомянул, я запускаю сопрограмму StartCoroutine(waitForTask(task, uid, name, email)); внутри другой сопрограммы (это, конечно, внутри другой курутины).Так что у меня много куртизанок.И большинство из них ждали некоторого объекта из предыдущей функции и т. Д. И я использую некоторый счетчик внутри цикла while.например,

while(obj == null && wait > 0) {
    wait--; 
    yield return new WaitForSceonds(1);
}
wait = 15;
//run next coroutine 

и переменная ожидания часто была одной для нескольких сопрограмм.Итак, что я изменил:

  1. Я больше не жду объект, но для выполнения специального задания (например, task.IsCompleted)
  2. Я изменил wait var на отметку времени.(например, я не хочу ждать, пока пользователь войдет в систему более 15 секунд)

Так что моей основной проблемы не было в коде, который я упомянул в вопросе.

Я обновлю свой ответ, когда найду время, чтобы изучить журналы Android и выяснить, почему сопрограммы сложены.

Вот пример с отметкой времени:

    private IEnumerator SetUserNameToTheTop()
    {
        while (ux.GetCurrentUser() == null && (DateTime.Now - dataTime).TotalSeconds < 15)
        {
            pendingTxt.text = (DateTime.Now - dataTime).TotalSeconds.ToString();
            Debug.Log("WAIT FOR ERROR");
            yield return new WaitForSeconds(1);
        }
        if (ux.GetCurrentUser() != null && ux.GetCurrentUser().userName != "")
        {
            ActivateMenu();
        }
        else
        {
            PENDING_MSG = "USER WASN'T FOUND, TRY TO SIGN UP FIRST";
            pendingTxt.text = PENDING_MSG;
            isFailed = true;
            FBButtons.SetActive(true);
        }
    }
...