I'm building a chat app using Firebase Realtime Database. I want to implement the functionality like WhatsApp, where the 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 sent yet).
When the Firebase Database receives the message (The user device connects to the internet and Firebase sends the message), I want to update the added element on the recyclerview(change the clock icon for a positive icon).
What have 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
where I get a dataSnapshot
of the new element, but I don't know how 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 an 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
}
}
});
Does someone have an idea why I cant accomplish that? Thanks. I search a lot before asked, but I didn't find the right 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.