Firebase Android:如何从不同的引用顺序读取 [英] Firebase Android: How to read from different references sequentially

查看:261
本文介绍了Firebase Android:如何从不同的引用顺序读取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



总之,我需要在一个用户引用来检查他目前在哪个课程中,然后我需要阅读课程的内容来加载它。


$ b $我现在做的是,我有两个嵌套的侦听器,像这样:

$ p $ ref $ addListenerForSingleValueEvent(new ValueEventListener (){
@Override
public void onDataChange(DataSnapshot dataSnapshot){

ref2.addListenerForSingleValueEvent(new ValueEventListener(){
@Override
public void onDataChange(DataSnapshot dataSnapshot){
//完成工作
}
});
}
});

有没有更好的方法来做这个查询,当你需要它们顺序?

解决方案

TL; DR



就像解析 JavaScript承诺。因此,您可以创建一系列任务,而不是嵌套监听器。



结果将发送到 addOnSuccessListener / android / p>

如果在用例执行过程中有任何失败,那么序列将被中止,异常被传递给 addOnFailureListener

  public Task< Course> < Void> forResult(null)
.then(new GetUser())
.then(new GetCourse());

$ b $ public void updateInBackground(){
Tasks。< Void> forResult(null)
.then(new GetUser())
。然后(new GetCourse())
.addOnSuccessListener(this)
.addOnFailureListener(this);

$ b @Override
public void onFailure(@NonNull异常错误){
Log.e(TAG,error.getMessage());

$ b @Override
public void onSuccess(Customer customer){
//对结果做一些事情
}
$ b $ h
$ b $ h

假设你想下载两个<$ c类型的对象$ c>用户和课程来自Firebase。



您需要创建第一个任务使用任务API 。您的选择是:





第一个选项主要是由于代码易读性。如果你需要在你自己的执行器中运行这些任务,你应该使用第一个或第二个选项。
$ b $现在让我们创建两个 继续一:

 类GetUser实现Continuation< Void,Task< User>> {

@Override
public Task< User>然后(Task< Void>任务){
final TaskCompletionSource< Course> tcs = new TaskCompletionSource();

ref1.addListenerForSingleValueEvent(new ValueEventListener(){
$ b @Override
public void onCancelled(DatabaseError error){
tcs.setException(error.toException ());
}

@Override
public void onDataChange(DataSnapshot snapshot){
tcs.setResult(snapshot.getValue(User.class));
}

});

return tcs.getTask();


$ b $ / code $ / pre
$ b $ p和$ / b

 类GetCourse实现Continuation< User,Task< Course>> {

@Override
public Task< Course>然后(Task< User>任务){
final User result = task.getResult();
final TaskCompletionSource< Course> tcs = new TaskCompletionSource();

ref2.addListenerForSingleValueEvent(new ValueEventListener(){
$ b @Override
public void onCancelled(DatabaseError error){
tcs.setException(error.toException ());
}

@Override
public void onDataChange(DataSnapshot snapshot){
tcs.setResult(snapshot.getValue(Course.class));
}

});

return tcs.getTask();


$ b

根据文档,请致电 getResult() ,并允许RuntimeExecutionException传播以传播完成的任务失败。



RuntimeExecutionException 将被解包,使得 continueWith(Continuation) continueWithTask(Continuation) 原始异常失败。


In one of my Android activities I need to perform multiple queries to Firebase to finally show something to the user.

In summary, I need to check in a Users reference to check which course step he is currently in, then I need to read the contents of the Course to load it.

What I´m currently doing is that I have two nested listeners like this:

ref1.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {

         ref2.addListenerForSingleValueEvent(new ValueEventListener() {
             @Override
             public void onDataChange(DataSnapshot dataSnapshot) {
                  //do the work
             }
         }); 
    }
}); 

Is there a better way to do this queries when you need them sequentially?

解决方案

TL;DR

Just like Parse did with Bolts, Google also provided a task framework that implement JavaScript promises. So, instead of nesting listeners, you can create a sequence of tasks.

The result will be sent to addOnSuccessListener if all tasks execute successfully.

If any of them fail during the use case execution, the sequence will be aborted and the exception is passed to addOnFailureListener.

public Task<Course> execute() {
    return Tasks.<Void>forResult(null)
        .then(new GetUser())
        .then(new GetCourse());
}

public void updateInBackground() {
    Tasks.<Void>forResult(null)
        .then(new GetUser())
        .then(new GetCourse())
        .addOnSuccessListener(this)
        .addOnFailureListener(this);
}

@Override
public void onFailure(@NonNull Exception error) {
    Log.e(TAG, error.getMessage());
}

@Override
public void onSuccess(Customer customer) {
    // Do something with the result
}

Description

Suppose you wish to download two object of type User and Course from Firebase.

You need to create the first task of your sequence using the Tasks API. Your options are:

I prefer the first option mostly due code legibility. If you you need run the tasks in your own executor, you should use the first or second option.

Now let's create two Continuation tasks two download each one:

class GetUser implements Continuation<Void, Task<User>> {

    @Override
    public Task<User> then(Task<Void> task) {
        final TaskCompletionSource<Course> tcs = new TaskCompletionSource();

        ref1.addListenerForSingleValueEvent(new ValueEventListener() {

            @Override
            public void onCancelled(DatabaseError error) {
                tcs.setException(error.toException());
            }

            @Override
            public void onDataChange(DataSnapshot snapshot) {
                tcs.setResult(snapshot.getValue(User.class));
            }

        });

        return tcs.getTask();
    }

}

and

class GetCourse implements Continuation<User, Task<Course>> {

    @Override
    public Task<Course> then(Task<User> task) {
        final User result = task.getResult();
        final TaskCompletionSource<Course> tcs = new TaskCompletionSource();

        ref2.addListenerForSingleValueEvent(new ValueEventListener() {

            @Override
            public void onCancelled(DatabaseError error) {
                tcs.setException(error.toException());
            }

            @Override
            public void onDataChange(DataSnapshot snapshot) {
                tcs.setResult(snapshot.getValue(Course.class));
            }

        });

        return tcs.getTask();
    }

}

According the documentation, call getResult() and allow the RuntimeExecutionException to propagate to propagate failure from the completed Task.

The RuntimeExecutionException will be unwrapped such that the Task returned by continueWith(Continuation) or continueWithTask(Continuation) fails with the original exception.

这篇关于Firebase Android:如何从不同的引用顺序读取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆