1

I want to create a chat app using Firebase Realtime Database with a RecyclerView and a CardView with the first name for every user.The problem is that it's only show me a cardview when I have 3 people in the database. I attached in this link a picture with my database:

The UsersFragment:

public class UsersFragment extends Fragment {
    private RecyclerView recyclerView;
    private UserAdapter userAdapter;
    private List<User> mUsers;


    @Override
    public View onCreateView (LayoutInflater inflater, ViewGroup container,
                              Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view= inflater.inflate ( R.layout.fragment_users3, container, false );
recyclerView=view.findViewById (R.id.recycler_view  );

recyclerView.setLayoutManager ( new LinearLayoutManager ( getContext () ) );
mUsers=new ArrayList<> (  );
readUsers();

        return view;
    }

    private void readUsers () {
        final FirebaseUser firebaseUser= FirebaseAuth.getInstance ().getCurrentUser ();
        DatabaseReference referenc= FirebaseDatabase.getInstance ().getReference ("users");

        referenc.addValueEventListener ( new ValueEventListener () {
            @Override
            public void onDataChange (@NonNull DataSnapshot dataSnapshot) {
                mUsers.clear ();
                for(DataSnapshot snapshot:dataSnapshot.getChildren ()){
                    User user=snapshot.getValue (User.class);
                    assert user!=null;
                    assert firebaseUser!=null;
                    if(!firebaseUser.getUid ().equals ( user.getUid () )){
                        mUsers.add ( user );

                    }
                }
                userAdapter=new UserAdapter ( getContext (),mUsers );
                recyclerView.setAdapter ( userAdapter );
            }

            @Override
            public void onCancelled (@NonNull DatabaseError databaseError) {

            }
        } );
    }


}

The UserAdapter.In i used the User class:

public class UserAdapter extends RecyclerView.Adapter<UserAdapter.ViewHolder> {
    private Context mContext;
    private List<User> mUsers;
    public UserAdapter(Context mContext,List<User> mUsers){
        this.mUsers=mUsers;
        this.mContext=mContext;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder (@NonNull ViewGroup parent, int viewType) {
        View view= LayoutInflater.from ( mContext ).inflate ( R.layout.users_template ,parent,false);

        return new UserAdapter.ViewHolder ( view );
    }

    @Override
    public void onBindViewHolder (@NonNull ViewHolder holder, int position) {
User user=mUsers.get ( position );
holder.username.setText ( user.getFirstName () );

    }

    @Override
    public int getItemCount () {
        return mUsers.size ();
    }

    public class ViewHolder extends RecyclerView.ViewHolder{

        public TextView username;

        public ViewHolder(View itemView){
            super(itemView);
            username=itemView.findViewById ( R.id.username1 );
        }

    }
}

The User that stores the FirstName :

public class User {
   public String firstName;
    public String secondName;
    public String uid;
    public String email;
    public User(){

    }



    public User (String firstName, String secondName, String uid, String email) {
        this.firstName = firstName;
        this.secondName = secondName;
        this.uid=uid;
        this.email=email;
    }

    public User (String firstname, String secondname) {
    }

    public String getFirstName () {
        return firstName;
    }

    public String getSecondName () {
        return secondName;
    }

    public String getUid () {
        return uid;
    }

    public String getEmail () {
        return email;
    }

    public void setFirstName (String firstName) {
        this.firstName = firstName;
    }

    public void setSecondName (String secondName) {
        this.secondName = secondName;
    }

    public void setUid (String uid) {
        this.uid = uid;
    }

    public void setEmail (String email) {
        this.email = email;
    }
}

And the activity where my TabLayout and ViewPager is

public class UsersActivity extends AppCompatActivity {


    @Override
    protected void onCreate (Bundle savedInstanceState) {
        super.onCreate ( savedInstanceState );
        setContentView ( R.layout.activity_users );
        TabLayout tablayout=findViewById ( R.id.tab_layout );
        ViewPager viewPager=findViewById ( R.id.view_pager );
        ViewPagerAdapter viewPagerAdapter=new ViewPagerAdapter ( getSupportFragmentManager () );
        viewPagerAdapter.addFragment ( new ChatFragment (),"Chats" );  // `new ChatFragment()` should be inside `FragmentPagerAdapter.getItem()`
        viewPagerAdapter.addFragment ( new UsersFragment (),"Users" );  // `new UsersFragment()` should be inside `FragmentPagerAdapter.getItem()`
        viewPager.setAdapter (viewPagerAdapter  );
        tablayout.setupWithViewPager (viewPager  );

    }
    class ViewPagerAdapter extends FragmentPagerAdapter{
private ArrayList<Fragment> fragments; // this line can cause crashes
private ArrayList<String> titles;
ViewPagerAdapter(FragmentManager fn){
    super(fn);
    this.fragments=new ArrayList<> (  );
    this.titles=new ArrayList<> (  );
}
        @NonNull
        @Override
        public Fragment getItem (int position) {
            return fragments.get ( position );
        }

        @Override
        public int getCount () {
            return fragments.size ();
        }
        public void addFragment(Fragment fragment,String title){
    fragments.add ( fragment ); // this line can cause crashes
    titles.add ( title );
        }

        @Nullable
        @Override
        public CharSequence getPageTitle (int position) {
            return titles.get ( position );
        }
    }
}

In the debug mode it show me:

W/ClassMapper: No setter/field for FirstName found on class com.example.sportsbuddy.User (fields/setters are case sensitive!)

I expect to show me all the users that I have in the database.

EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428

2 Answers2

1

Change the keys in the firebase database to be firstName, secondName, email rather than FirstName,SecondName and E-mail. The data from the firebase cannot be mapped if the correct keys and their getters and setters are not found in model class.

Antonio
  • 1,264
  • 7
  • 12
0

You have a property FirstName in your JSON in the database. In your User class, you have a method getFirstName(), which corresponds (according to the JavaBean convention that Firebase uses) to a property firstName. Since the case is different, that is a different property.

To make the JSON and the class match, you can change the JSON to use JavaBean property names:

{
  "users": {
    "uid1": {
      "email": "...",
      "firstName": "...",
      "secondName": "..."
    }
  }
}

Alternatively you can make the Java class match your current JSON by using the PropertyName attribute:

public class User {
    private String firstName;
    private String secondName;
    private String uid;
    private String email;

    public User(){
    }

    public User (String firstName, String secondName, String uid, String email) {
        this.firstName = firstName;
        this.secondName = secondName;
        this.uid=uid;
        this.email=email;
    }

    public User (String firstname, String secondname) {
    }

    @PropertyName("FirstName")
    public String getFirstName () {
        return firstName;
    }

    @PropertyName("SecondName")
    public String getSecondName () {
        return secondName;
    }

    @PropertyName("Uid")
    public String getUid () {
        return uid;
    }

    @PropertyName("E-mail")
    public String getEmail () {
        return email;
    }

    @PropertyName("FirstName")
    public void setFirstName (String firstName) {
        this.firstName = firstName;
    }

    @PropertyName("SecondName")
    public void setSecondName (String secondName) {
        this.secondName = secondName;
    }

    @PropertyName("Uid")
    public void setUid (String uid) {
        this.uid = uid;
    }

    @PropertyName("E-mail")
    public void setEmail (String email) {
        this.email = email;
    }
}

Also see my answer here: Specifying serialized names in java class for firestore document

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • I did what you told me and in the debugger it shows me "at com.example.sportsbuddy.Fragments.UsersFragment$1.onDataChange(UsersFragment.java:60)" and my app crashes.What can I do? – Cosmin Zahariea Jun 29 '19 at 09:37
  • If your app crashes, find the complete error message and stack trace and add them here, or in your question (since there you can format them to be more readable). Btw: I gave you two options to solve your problem. It'd probably be helpful to know which one of the two you used. – Frank van Puffelen Jun 29 '19 at 12:22
  • I also updated my answer here for the problem in your other post. – Frank van Puffelen Jun 29 '19 at 12:34