Firebase Android:如何按顺序读取不同的引用 [英] Firebase Android: How to read from different references sequentially
问题描述
在我的一项 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
就像 Parse 对 Bolts,谷歌也提供了一个实现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 下载 User
和 Course
类型的两个对象.
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:
- 使用
Tasks.forResult
- 创建一个
TaskCompletionSource
,设置结果或异常值,然后返回一个任务. - 从
可调用
.
- 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屋!