Azizjon Kholmatov
Azizjon Kholmatov

Reputation: 1266

How to pass a database reference (coming from Callback) to FirebaseRecyclerAdapter

I am in the sitatuion where I have to get firebase database ref from Callback. It is working pretty fine since I am able to read/write to the database.

public void readData(final MyCallback myCallback) {
    mCurrentUserDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            String university = dataSnapshot.child("university").getValue().toString();
            String groupid = dataSnapshot.child("groupid").getValue().toString();
            //Having acquired university and group ID, now we can get reference to group members list
            mMembersDatabase = FirebaseDatabase.getInstance().getReference().child("Universities").child(university).child("Groups").child(groupid).child("Members");
            myCallback.onCallback(mMembersDatabase);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {}
    });
}

Then, in onStart() method of my activity, I am creating my FirebaseRecyclerAdapter. Since it requires 4 parameters:

I need to pass the firebase database ref i am getting from the my Callback as a parameter. I tried the following in onStart(), but it is not working.

    readData(new MyCallback() {
        @Override
        public void onCallback(DatabaseReference databaseReference) {


           FirebaseRecyclerAdapter<Groupmates, GroupmatesViewHolder> firebaseRecyclerAdapter =
            new FirebaseRecyclerAdapter <Groupmates, GroupmatesViewHolder> (
                    Groupmates.class,
                    R.layout.users_single_layout,
                    GroupmatesViewHolder.class,
                    databaseReference
            ) {
                @Override
                protected  void populateViewHolder(final GroupmatesViewHolder groupmatesViewHolder, final Groupmates groupmates, final int position) {
                                 //SOME LOGIC HERE
                }
            };
    //Finally, setting the ready adapter to the RecyclerView
    mGroupmatesList.setAdapter(firebaseRecyclerAdapter);

        }
    });

I am receiving null object reference exception if I try to create FirebaseRecyclerAdapter outside of my Callback.

I can't really get my way out of it. Any suggestions would be helpful.

Upvotes: 1

Views: 346

Answers (2)

Azizjon Kholmatov
Azizjon Kholmatov

Reputation: 1266

After spending a day of researching, I finally found the solution. I would like to thank @Alex Mamo for the correct guidence and direction he provided. However, it was NOT enough to solve the problem. That's why I am answering my own question.

After getting the FirebaseDatabaseReference from Callback, my recycler view was still not getting populated. Thus, simply getting database ref via Callback might not be enough to see the final result. With the help of answer to this question and combination of suggestions and guidence provided by @Alex Mamo, I was able to solve the issue.

So answer is simple: I just called my Callback inside onCreateView(). Then created my FirebaseReyclerAdapter inside the Callback Method. When the adapter is being created, before setting the adapter to RecyclerView there was a need to add AdapterDataObsever to the adapter.

firebaseRecyclerAdapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
                @Override
                public void onItemRangeInserted(int positionStart, int itemCount) {
                    super.onItemRangeInserted(positionStart, itemCount);
                    int groupmate_count = firebaseRecyclerAdapter.getItemCount();
                    int lastVisiblePosition = mLinearLayoutManager.findLastVisibleItemPosition();
                    // If the recycler view is initially being loaded or the
                    // user is at the bottom of the list, scroll to the bottom
                    // of the list to show the newly added message.
                    if (lastVisiblePosition == -1 ||  (positionStart >= (groupmate_count - 1) && lastVisiblePosition == (positionStart - 1))) {
                        mGroupmatesList.scrollToPosition(positionStart);
                    }
                }
            });

This is working pretty nice. Hope it helps others too.

Upvotes: 0

Alex Mamo
Alex Mamo

Reputation: 1

If I were you, I'll move the declaration of FirebaseRecyclerAdapter inside onDataChange() so you can easily pass the mMembersDatabase to the constructor and then change the callback like this:

public interface MyCallback {
    void onCallback(FirebaseRecyclerAdapter firebaseRecyclerAdapter);
}

The use the following code:

public void readData(final MyCallback myCallback) {
    mCurrentUserDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        String university = dataSnapshot.child("university").getValue().toString();
        String groupid = dataSnapshot.child("groupid").getValue().toString();
        //Having acquired university and group ID, now we can get reference to group members list
        mMembersDatabase = FirebaseDatabase.getInstance().getReference().child("Universities").child(university).child("Groups").child(groupid).child("Members");

        FirebaseRecyclerAdapter<Groupmates, GroupmatesViewHolder> firebaseRecyclerAdapter =
        new FirebaseRecyclerAdapter <Groupmates, GroupmatesViewHolder> (
            Groupmates.class,
            R.layout.users_single_layout,
            GroupmatesViewHolder.class,
            mMembersDatabase
        ) {
             @Override
             protected  void populateViewHolder(final GroupmatesViewHolder groupmatesViewHolder, final Groupmates groupmates, final int position) {
                 //SOME LOGIC HERE
             }
        };
        myCallback.onCallback(firebaseRecyclerAdapter);
    }

    @Override
        public void onCancelled(DatabaseError databaseError) {}
    });
}

And then in your onStart(), use this:

readData(new MyCallback() {
    @Override
    public void onCallback(FirebaseRecyclerAdapter firebaseRecyclerAdapter) {
        mGroupmatesList.setAdapter(firebaseRecyclerAdapter);
    }
});

Upvotes: 1

Related Questions