Как получить последний идентификатор из консоли Firebase от Untiy - PullRequest
0 голосов
/ 19 февраля 2020

У меня есть проект Unity с Firebase для аутентификации Google. Я храню информацию о пользователях в базе данных в реальном времени. Они хранятся как:

UnityProject
    1->
       Name: "Something"
       Email: "Something"
    2->
       Name: "some other thing"
       Email: "Something else"

Теперь эти 1,2 должны быть предоставлены мной (для использования в качестве первичного ключа). Я хотел бы начать с предоставления первого идентификатора пользователя 1, второго использованного идентификатора 2 и так далее.

Но мне нужно вернуть из базы данных последний сохраненный идентификатор. Например,

idToInsert = GetLastUsedID() + 1;

Я использовал этот код, но он не работает. Экран просто зависает, пока я не принудительно закрою Unity.

 public int GetLastUsedID()
    {
        int currentID = 1;
        bool continueSearch = true;

        while (continueSearch)
        {
            FirebaseREST.DatabaseReference reference = FirebaseREST.FirebaseDatabase.Instance.GetReference(""+currentID);
            string value = "";
            currentID++;
            reference.GetValueAsync(10, (res) =>
            {
                if (res.success)
                {
                    value = res.data.GetRawJsonValue();
                    Debug.Log("Success fetched data : " + value);
                    if(value == "")
                    {
                        continueSearch = false;
                        Debug.Log(currentID);
                    }
                }
                else
                {
                    Debug.Log("Fetch data failed : " + res.message);
                    continueSearch = false;
                }
            });

        }
        return currentID;
}

По сути, я просто пытаюсь перебирать от 1 до всякий раз, когда получаю пустую строку. Пустая строка означает, что под этим идентификатором не существует данных.

1 Ответ

1 голос
/ 20 февраля 2020

Я не знаком с FirebaseREST (я бы порекомендовал использовать официальный плагин Firebase *1003*, если вы можете, это гораздо больше, чем просто вызов конечных точек REST), но я думаю, что вижу Ваша проблема.

GetValueAsync, вероятно, работает в фоновом режиме асинхронно. Таким образом, логика c внутри блока (часть (res)=>) запускается много раз (в основном бесконечно с этим, в то время как l oop). Затем, в зависимости от того, как это реализовано, либо continueSearch никогда не переходит к false, потому что он не помечен volatile , либо logi обратного вызова c никогда не получает шанс на запуск (скажем, если FirebaseREST пытается отправить в основной поток, который заблокирован бесконечно, пока l oop).

Если GetValueAsync возвращает задание, вы можете использовать некоторые из советов, которые я рассмотрел в this статья . Я бы порекомендовал попробовать использовать async / await, чтобы ваш лог c выглядел так:

async public int GetLastUsedID()
{
    volatile int currentID = 1;
    volatile bool continueSearch = true;

    while (continueSearch)
    {
        FirebaseREST.DatabaseReference reference = FirebaseREST.FirebaseDatabase.Instance.GetReference(""+currentID);
        string value = "";
        currentID++;
        await reference.GetValueAsync(10, (res) =>
        {
            if (res.success)
            {
                value = res.data.GetRawJsonValue();
                Debug.Log("Success fetched data : " + value);
                if(value == "")
                {
                    continueSearch = false;
                    Debug.Log(currentID);
                }
            }
            else
            {
                Debug.Log("Fetch data failed : " + res.message);
                continueSearch = false;
            }
        });
    }
    return currentID;
}

Это, вероятно, не тот случай, в этом случае вы, вероятно, захотите включить это в рекурсивный вызов. Вы бы хотели какую-то функцию, такую ​​как:

public void GetLastUsedID(currentId)
{
        FirebaseREST.DatabaseReference reference = FirebaseREST.FirebaseDatabase.Instance.GetReference(""+currentID);
        reference.GetValueAsync(10, (res) =>
        {
            if (res.success)
            {
                value = res.data.GetRawJsonValue();
                Debug.Log("Success fetched data : " + value);
                if(value == "")
                {
                    continueSearch = false;
                    Debug.Log(currentID);
                }
                else
                {
                    // recurse
                    GetLastID(currentId+1);
                }
            }
            else
            {
                Debug.Log("Fetch data failed : " + res.message);
                continueSearch = false;
            }
        });
}

Вы должны будете выяснить, как передать свой собственный обратный вызов, чтобы описать такой успех или неудачу (упражнение для читателя).

Наконец, я буду немного осторожен с тем, что вы делаете полностью. Если вы аутентифицируете пользователей, я бы рекомендовал использовать Firebase Authentication , которая напрямую связана с базой данных реального времени. Самое большее, вы можете хранить там только идентификаторы пользователей и использовать правила безопасности , чтобы гарантировать, что только этот пользователь может писать в него (например). Используя Firebase Authentication для управления пользовательскими данными и привязывая их к правилам RTDB, вы избежите тех же ошибок , которые автор сделал .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...