Можно ли отправить синхронный запрос в Firebase?

Я использую Firebase Android SDK и заинтересовался отправкой синхронного запроса вместо асинхронного. Согласно документации, в любом запросе представлены обратные вызовы. Но как насчет синхронности?

Спасибо!

Ответ 1

Невозможно синхронно загружать данные из базы данных Firebase.

В то время как для разработчиков, новых для Firebase, для разработчиков синхронный метод, он просто не подходит для модели синхронизации данных Firebase. Также см. Мой ответ здесь: Установка значения свойства Singleton в Firebase Listener

Ответ 2

Невозможно загрузить данные асинхронно с официальным SDK. Однако вы можете получить доступ ко всем данным в firebase, используя REST API. Это позволит вам совершать синхронные вызовы. Как уже упоминалось, Firebase - это база данных в реальном времени, и при изменении ваших данных будет отсутствовать функция обновлений.

Ответ 3

Хотя невозможно загрузить данные из FirebaseDatabase синхронно, можно подождать, пока загрузка завершится синхронно.

Вы можете CountDownLatch слушатель значения в CountDownLatch и вести CountDownLatch отсчет после onDataChange реализации onDataChange или onCancelled.

Это на самом деле то, что API- Tasks.await(someTask) Tasks делает внутри, если вы вызываете Tasks.await(someTask).

Вы должны использовать значение listener для прослушивания одного события, потому что в этом случае я предполагаю, что вы не хотите продолжать обновления. И используйте правильное время ожидания для CountDownLatch, так как Firebase никогда не будет CountDownLatch ожидания.

reference.addListenerForSingleValueEvent(...);

Вы также должны принять во внимание, что если у вас включен кэш FirebaseDatabase, первый результат может не соответствовать фактическому значению на сервере.

Я должен добавить: хотя это может сработать, это противоречит идее о том, как проектируется и должен использоваться база firebase, как уже сказал Фрэнк.

Ответ 4

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

TasksManager.class

public class TasksManager {

    ...

    public ExecutorService getExecutor() {
        if (mDefaultExecutor == null || mDefaultExecutor.isShutdown() || mDefaultExecutor.isTerminated()) {
            // Create a new ThreadPoolExecutor with 2 threads for each processor on the
            // device and a 60 second keep-alive time.
            int numCores = Runtime.getRuntime().availableProcessors();
            ThreadPoolExecutor executor = new ThreadPoolExecutor(
                    numCores * 2,
                    numCores * 2,
                    60L,
                    TimeUnit.SECONDS,
                    new LinkedBlockingQueue<>()
            );
            mDefaultExecutor = executor;
        }
        return mDefaultExecutor;
    }

    public static <TResult> Task<TResult> call(@NonNull Callable<TResult> callable) {
        return Tasks.call(getInstance().getExecutor(), callable);
    }
}

Вот пример кода для его использования.

TasksManager.call(() -> {
    Tasks.await(AuthManager.signInAnonymously());

    // You can use multiple Tasks.await method here.
    // Tasks.await(getUserTask());
    // Tasks.await(getProfileTask());
    // Tasks.await(moreAwesomeTask());
    // ...

    startMainActivity();
    return null;
}).addOnFailureListener(e -> {
    Log.w(TAG, "signInAnonymously:ERROR", e);
});