是否可以在Firebase中发送同步请求?

时间:2016-03-03 18:08:11

标签: android firebase

我使用Firebase Android SDK并且对发送同步请求而不是异步感兴趣。根据文档,在任何请求中都会显示回调。但是同步性呢?

谢谢!

4 个答案:

答案 0 :(得分:6)

无法从Firebase数据库同步加载数据。

虽然新手Firebase的开发人员希望采用同步方法,但它根本不适合Firebase的数据同步模型。另请参阅我的答案:Setting Singleton property value in Firebase Listener

答案 1 :(得分:5)

无法与官方SDK异步加载数据。但是,您可以使用REST API访问firebase中的所有数据。这将允许您进行同步调用。如上所述,Firebase是一个实时数据库,当您的数据发生变化时,您将缺少更新功能。

答案 2 :(得分:0)

虽然无法以同步方式从FirebaseDatabase加载数据,但可以等待加载同步完成。

您可以将值监听器包装在CountDownLatch中,然后递减计数, 一旦调用onDataChangeonCancelled实现。

这实际上是 Tasks api在内部执行的操作,如果您调用Tasks.await(someTask)

您应该将值侦听器用于单个事件侦听,因为在这种情况下,我假设您不希望继续更新。并为CountDownLatch使用适当的超时,因为Firebase不会超时,永远

reference.addListenerForSingleValueEvent(...);

您还必须考虑到,如果您具有 FirebaseDatabase 缓存,则第一个结果可能不是 服务器。

我必须补充:尽管这可能行得通,但正如弗兰克已经说过的那样,反对如何设计和使用Firebase的想法。

答案 3 :(得分:0)

我做了一个简单的类,可以在Android中同步调用任务。
请注意,这类似于Javascript的异步等待功能。
检查我的gist

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);
});