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

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

问题描述

在我的一项 Android 活动中,我需要对 Firebase 执行多个查询,以最终向用户显示某些内容.

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

就像 ParseBolts,谷歌也提供了一个实现JavaScript 承诺.因此,您可以创建一系列任务,而不是嵌套侦听器.

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.

结果将发送到addOnSuccessListener 如果所有任务都成功执行.

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

如果其中任何一个在用例执行期间失败,序列将被中止并将异常传递给 addOnFailureListener.

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
}

说明

假设您希望从 Firebase 下载 UserCourse 类型的两个对象.

Description

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

您需要使用 Tasks API 创建序列的第一个任务.您的选择是:

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

  • Create a successful task using Tasks.forResult
  • Create a TaskCompletionSource, set the result or exception values, then return a task.
  • Create a task from a callable.

我更喜欢第一个选项,主要是因为代码易读.如果您需要在自己的执行器中运行任务,则应使用第一个或第二个选项.

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.

现在让我们创建两个Continuation 任务二下载各一个:

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

}

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

}

根据文档,调用getResult() 并允许 RuntimeExecutionException 传播以从已完成的任务传播失败.

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

RuntimeExecutionException 将被解包,以便 continueWith(Continuation)continueWithTask(Continuation) 因原始异常而失败.

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天全站免登陆