是否有可能从Firebase同步加载数据?

我正在尝试使用通过Firebase连接的对等数据更新Android应用程序中WebView的部分内容。 为此,执行将返回所需数据的阻塞操作会很有帮助。 例如,聊天示例的实现将等待另一个聊天参与者在push.setValue()返回之前写入某个内容。 Firebase有这种行为吗?

Solutions Collecting From Web of "是否有可能从Firebase同步加载数据?"

在常规的JVM上,你可以使用普通的Java同步原语来完成这个任务。

例如:

// create a java.util.concurrent.Semaphore with 0 initial permits final Semaphore semaphore = new Semaphore(0); // attach a value listener to a Firebase reference ref.addValueEventListener(new ValueEventListener() { // onDataChange will execute when the current value loaded and whenever it changes @Override public void onDataChange(DataSnapshot dataSnapshot) { // TODO: do whatever you need to do with the dataSnapshot // tell the caller that we're done semaphore.release(); } @Override public void onCancelled(FirebaseError firebaseError) { } }); // wait until the onDataChange callback has released the semaphore semaphore.acquire(); // send our response message ref.push().setValue("Oh really? Here is what I think of that"); 

但是这不适用于Android。 这是一件好事,因为在影响用户界面的任何事情中使用这种types的阻塞方法是一个坏主意。 我使用这个代码的唯一原因是因为我需要进行unit testing。

在真正的面向用户的代码中,您应该采用事件驱动的方法。 因此,我不会“等待数据来,然后发送我的消息”,而是“当数据进入时,发送我的消息”:

 // attach a value listener to a Firebase reference ref.addValueEventListener(new ValueEventListener() { // onDataChange will execute when the current value loaded and whenever it changes @Override public void onDataChange(DataSnapshot dataSnapshot) { // TODO: do whatever you need to do with the dataSnapshot // send our response message ref.push().setValue("Oh really? Here is what I think of that!"); } @Override public void onCancelled(FirebaseError firebaseError) { } }); 

最终的结果是完全一样的,但是这个代码不需要同步,并且不会在Android上阻塞。

包com.google.android.gms.tasks;

Tasks.await(taskFromFirebase);

我想出了另一种同步获取数据的方法。 先决条件是不在UI线程上。

 final TaskCompletionSource<List<Objects>> tcs = new TaskCompletionSource<>(); firebaseDatabase.getReference().child("objects").addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { Mapper<DataSnapshot, List<Object>> mapper = new SnapshotToObjects(); tcs.setResult(mapper.map(dataSnapshot)); } @Override public void onCancelled(DatabaseError databaseError) { tcs.setException(databaseError.toException()); } }); Task<List<Object>> t = tcs.getTask(); try { Tasks.await(t); } catch (ExecutionException | InterruptedException e) { t = Tasks.forException(e); } if(t.isSuccessful()) { List<Object> result = t.getResult(); } 

我testing了我的解决scheme,它工作正常,但请certificate我错了!