Search code examples
androidfirebaseandroid-recyclerviewfirebase-realtime-databasefirebaseui

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 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.


Solution

  • 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.