Guilhermino Afonso Guilhermino Afonso - 2 months ago 44
Android Question

Update recyclerview item ui in client to indicate that Firebase Database on server got updated

I'm building a chat app using Firebase Realtime Database. I want to implement the functionality like whattsApp, that user can send the message without internet(Add the message object on RecyclerView) but will have the clock icon(To show that the message was not send yet) and when the Firebase database receive the message(The user get internet and firebase send the message) I want to update the added element on recyclerview(change the clock icon for a positive icon).

What I tried?

I have that

mFirebaseDatabaseReference = FirebaseDatabase.getInstance().getReference();
mFirebaseAdapter = new ChatFirebaseAdapter(mFirebaseDatabaseReference.child("chat_id"), user.getId());
recyclerChat.setLayoutManager(mLinearLayoutManager);
recyclerChat.setAdapter(mFirebaseAdapter);


My adapter extends FirebaseRecyclerAdapter from firebase-ui-database

I tried to add a addChildEventListener on my DatabaseReference I get dataSnapshot of the new element but I don't known I to get the right position on recyclerview.

mFirebaseDatabaseReference.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
UPDATE RECYCLERVIEW ITEM
}

@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {

}

@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {

}

@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {

}

@Override
public void onCancelled(DatabaseError databaseError) {

}
});


I added a onCompletionListener when I add a new message but I don't know how get the right position again.

mFirebaseDatabaseReference.push().setValue(message, new DatabaseReference.CompletionListener() {
@Override
public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) {
if (databaseError == null) {
UPDATE RECYCLERVIEW ITEM
}
}
});


So someone have an idea how I cant accomplish that?

Thanks. I search a lot before ask but I don't find the right answer.

Answer

The solution to your problem lies in adding a delivered boolean which can be set to true and once you receive successful push id from your code in onCompletionListener, then all you need to do is set this boolean to that particular push id.

Now on your android client in your firebase ui you can check if this boolean is set to true and change the state of recycler view items accordingly. This solution will work because firebase database is real-time.

//setting boolean onComplete

mFirebaseDatabaseReference.push().setValue(message, new DatabaseReference.CompletionListener() { @Override public void onComplete(DatabaseError databaseError, DatabaseReference databaseReference) { if (databaseError == null) { databaseReference.child("delivered").setValue(true); } } });

For chat apps like whatsapp, messenger etc you would take another messaging route if not using firebase as backened. Which I am not discussing here as it is out of scope of asked question.