猿问

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

我正在尝试使用从通过Firebase连接的对等方获取的数据更新Android应用程序中WebView的部分。为此,执行将返回所需数据的阻塞操作可能会有所帮助。例如,Chat示例的一个实现将等到另一个聊天参与者在push.setValue()返回之前写一些东西之后再执行。Firebase是否可能出现这种现象?



呼如林
浏览 727回答 3
3回答

白衣染霜花

在常规JVM上,可以使用常规Java同步原语来实现。例如:// create a java.util.concurrent.Semaphore with 0 initial permitsfinal Semaphore semaphore = new Semaphore(0);// attach a value listener to a Firebase referenceref.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 semaphoresemaphore.acquire();// send our response messageref.push().setValue("Oh really? Here is what I think of that");但这在Android上不起作用。这是一件好事,因为在影响用户界面的任何事物中使用这种类型的阻止方法都是一个坏主意。我留下这些代码的唯一原因是因为我需要进行单元测试。在实际的面向用户的代码中,您应该采用事件驱动的方法。因此,我会“当数据进入时,发送我的消息”,而不是“等待数据到达然后发送我的消息”:// attach a value listener to a Firebase referenceref.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上不会阻塞。

开心每一天1111

import com.google.android.gms.tasks.Tasks;Tasks.await(taskFromFirebase);

翻阅古今

我想出了另一种同步获取数据的方式。前提条件是不在UI线程上。final TaskCompletionSource<List<Objects>> tcs = new TaskCompletionSource<>();firebaseDatabase.getReference().child("objects").addListenerForSingleValueEvent(new ValueEventListener() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public void onDataChange(DataSnapshot dataSnapshot) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Mapper<DataSnapshot, List<Object>> mapper = new SnapshotToObjects();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tcs.setResult(mapper.map(dataSnapshot));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; @Override&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; public void onCancelled(DatabaseError databaseError) {&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tcs.setException(databaseError.toException());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; });Task<List<Object>> t = tcs.getTask();try {&nbsp; &nbsp; Tasks.await(t);} catch (ExecutionException | InterruptedException e) {&nbsp; &nbsp; t = Tasks.forException(e);}if(t.isSuccessful()) {&nbsp; &nbsp; List<Object> result = t.getResult();}我测试了我的解决方案,它工作正常,但请证明我错了!
随时随地看视频慕课网APP

相关分类

Android
我要回答