好的,所以我想做的是从firebase收集一个user_uid的列表,然后为每个user_uid获取一个图像URL并将其组合并返回一个Object。我遇到的问题是从异步调用返回对象。我正在尝试实现rxjava来实现这一点,但是我仍在获取空对象。下面,我将提供代码和数据库结构,以便您可以了解我要实现的目标,在此感谢所有高级帮助
这是数据库结构: http://oi63.tinypic.com/hsmio6.jpg
异步呼叫:
private Note createNoteWithArtists(Note note, ArrayList<String> user_uids) {
DatabaseReference db_users = db_root.child("Users");
ArrayList<User> artists = new ArrayList<>();
Note note = note;
for (String each_uid : user_uids) {
db_users.child(each_uid).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
String uid = dataSnapshot.getKey();
String image = dataSnapshot.child("image").getValue(String.class);
String username = dataSnapshot.child("username").getValue(String.class);
User user = new User(username, null, image, uid);
artists.add(user);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
}
});
}
note.setArtists(artists);
return Note;
}
试图使用RxJava:
io.reactivex.Observable<Note> observable = io.reactivex.Observable.create(subscriber -> {
subscriber.onNext(createNoteWithArtists(note, artists));
subscriber.onComplete();
});
observable.subscribe(note -> loadNoteResults.NoteLoaded(note, true)).dispose();
它返回注释,但是嵌套的artist对象仍然为空:/
答案 0 :(得分:0)
Observable.create(...)
将在Note
返回值后发出createNotWitArtists
。您的RxJava尝试在功能上等同于:
Note emptyNote = createNoteWithArtists(note, artists);
loadNoteResults.NoteLoaded(emptyNote , true);
看看这种方法:
private Single<User> getUser(String user_uid) {
DatabaseReference db_users = db_root.child("Users");
return Single.create(emitter -> {
db_users.child(each_uid).addListenerForSingleValueEvent(new ValueEventListener() {
@Override
public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
String uid = dataSnapshot.getKey();
String image = dataSnapshot.child("image").getValue(String.class);
String username = dataSnapshot.child("username").getValue(String.class);
User user = new User(username, null, image, uid);
emitter.onSuccess(user);
}
@Override
public void onCancelled(@NonNull DatabaseError databaseError) {
emitter.onError(databaseError);
}
});
});
}
这个想法是使用Single.create
,它在每个onDataChange
被调用时发出。
然后,您可以像这样使用Single
合并所有toList()
:
// Note note
// List<String> artist
Observable.fromIterable(artistIds) // Observable<String>
.flatMapSingle(this::getUser) // Observable<User>
.toList() // Single<List<User>>
.subscribe( artists -> {
note.setArtists(artists);
loadNoteResults.NoteLoaded(note, true);
});
此外,别忘了在需要时放置调度程序。