2

Okay, so what I'm trying to do is collect a list of user_uid's from firebase then for each user_uid fetch an image url and combine it and return one Object. The problem I'm running into is returning the Object from the asynchronous call. I'm trying to implement rxjava to achieve this, but I'm still getting empty Objects. below I'll have code and database structure so you can see what I'm trying to achieve, thank you all in advanced for any help

this is the database structure: enter image description here

Asynchronous call:

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

attempting to use 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();

It returns the note, but the nested artists object is still empty :/

1 Answer 1

2

Observable.create(...) will emit a Note as soon as createNotWitArtists returns a value. Your RxJava attempt is functionally equivalent to:

Note emptyNote = createNoteWithArtists(note, artists);
loadNoteResults.NoteLoaded(emptyNote , true);

Take a look at this approach:

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

The idea is to use Single.create that emits when each onDataChange is called.

Then you can combine all Singles using toList() like this:

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

Also, don't forget to put schedulers whenever it is needed.

Sign up to request clarification or add additional context in comments.

1 Comment

Yes, this is exactly what i was trying to achieve! I'm new to Rxjava and seeing this implementation helps a lot with seeing what's going on where, and how to use the received information. thank you so much

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.