为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

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

3 回答

?
白衣染霜花

TA贡献1796条经验 获得超10个赞

在常规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上不起作用。这是一件好事,因为在影响用户界面的任何事物中使用这种类型的阻止方法都是一个坏主意。我留下这些代码的唯一原因是因为我需要进行单元测试。


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


// 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上不会阻塞。


查看完整回答
反对 回复 2019-12-04
?
开心每一天1111

TA贡献1836条经验 获得超13个赞

import com.google.android.gms.tasks.Tasks;


Tasks.await(taskFromFirebase);


查看完整回答
反对 回复 2019-12-04
?
翻阅古今

TA贡献1780条经验 获得超5个赞

我想出了另一种同步获取数据的方式。前提条件是不在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();

}

我测试了我的解决方案,它工作正常,但请证明我错了!


查看完整回答
反对 回复 2019-12-04
  • 3 回答
  • 0 关注
  • 673 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信