Get firebase database records to RecyclerView - java

I'm recently learning about firebase database. Now I'm trying to put the records to RecyclerView
Here is what I do
BiodataModel value;
DatabaseReference mdatabase;
private List<BiodataModel> mBiodata;
BiodataAdapter dAdapter;
List<BiodataModel> userlist = new ArrayList<>();
mdatabase = FirebaseDatabase.getInstance().getReference().child("Biodata");
mdatabase.keepSynced(true);
mdatabase.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
userlist = new ArrayList<>();
if (dataSnapshot != null && dataSnapshot.getValue() != null) {
try {
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
BiodataModel bioModel = postSnapshot.getValue(BiodataModel.class); // The problem is here
userlist.add(bioModel);
}
} catch (Exception ex) {
Log.e("MYERROR", ex.getMessage());
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.d("MYERROR", databaseError.getMessage());
}
});
Here is my adapter
public class BiodataAdapter extends RecyclerView.Adapter<BiodataAdapter.MyViewHolder>{
private List<BiodataModel> bioList;
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView fullname;
public MyViewHolder(View view) {
super(view);
fullname = (TextView) view.findViewById(R.id.fullname);
}
}
public BiodataAdapter(){
}
public BiodataAdapter(List<BiodataModel> bioList) {
this.bioList = bioList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.biodata_list_row, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
BiodataModel bio = bioList.get(position);
holder.fullname.setText(bio.getFullname());
}
#Override
public int getItemCount() {
return bioList.size();
}
}
and this is my Model
public class BiodataModel {
public String fullname,email,noTelp,alamat;
public BiodataModel(String fullname, String email, String noTelp,String alamat){
this.fullname = fullname;
this.email = email;
this.noTelp = noTelp;
this.alamat = alamat;
}
public String getFullname() {
return fullname;
}
public String getEmail() {
return email;
}
public String getNoTelp() {
return noTelp;
}
public String getAlamat() {
return alamat;
}
public void setFullname(String fullname) {
this.fullname = fullname;
}
public void setEmail(String email) {
this.email = email;
}
public void setNoTelp(String noTelp) {
this.noTelp = noTelp;
}
public void setAlamat(String alamat) {
this.alamat = alamat;
}
}
and i get this error
Can't convert object of type java.lang.String to type
ZZZZ.BiodataModel
how can i fix it ?

Your reference is this:
mdatabase = FirebaseDatabase.getInstance().getReference().child("Biodata");
so at child Biodata, then you are iterating inside it's direct child for (DataSnapshot postSnapshot : dataSnapshot.getChildren()), thus retrieving the Strings Alamat,Email.
To solve this, you need to remove the for loop and try the following:
mdatabase.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
userlist = new ArrayList<>();
if (dataSnapshot != null && dataSnapshot.getValue() != null) {
try {
BiodataModel bioModel = dataSnapshot.getValue(BiodataModel.class);
userlist.add(bioModel);
} catch (Exception ex) {
Log.e("MYERROR", ex.getMessage());
}
}
}

Related

Display data into RecyclerView

I never understood how SQL Database works. So I searched a little and found this library. I'm still trying it.
I want to display the data into a RecyclerView using a RecyclerAdapter. I have always worked with it and I know how to do it but only using Cloud Firestore. So my question is: how to display the data in that database library that I have found into the RecyclerView?
I have written the adapter code and created the model class. I still need the part where the data are displayed.
This is how to read all data:
Cursor res = easyDB.getAllData();
while (res.moveToNext()) {
int anIntegerVariable = res.getInt(columnIndex);
String aStringVariable = res.getString(columnIndex);
}
User.java
public class User {
String id, name, password;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public User(String id, String name, String password) {
this.id = id;
this.name = name;
this.password = password;
}
public User() {
}
}
UsersRecyclerAdapater.java
public class UsersRecyclerAdapater extends RecyclerView.Adapter<UsersRecyclerAdapater.ViewHolder> {
public List<User> userList;
public Context context;
public UsersRecyclerAdapater(Context context, List<User> userList) {
this.userList = userList;
this.context = context;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.user_list_item, parent, false);
context = parent.getContext();
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull final ViewHolder holder, int position) {
holder.setIsRecyclable(false);
String id = userList.get(position).getId();
String name = userList.get(position).getName();
String password = userList.get(position).getPassword();
holder.setIdView(id);
holder.setName(name);
holder.setPasswordView(password);
}
#Override
public int getItemCount() {
return userList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
private TextView idView;
private TextView nameView;
private TextView passwordView;
public View view;
public ViewHolder(#NonNull View itemView) {
super(itemView);
view = itemView;
}
public void setIdView(String id) {
idView = view.findViewById(R.id.user_id);
idView.setText(id);
}
public void setName(String name) {
nameView = view.findViewById(R.id.user_name);
nameView.setText(name);
}
public void setPasswordView(String password) {
passwordView = view.findViewById(R.id.user_password);
passwordView.setText(password);
}
}
}
MainActivity.java
easyDB = EasyDB.init(this, DATABASE_NAME)
.setTableName(TABLE_NAME)
.addColumn(new Column(NAME_COLUMN, "TEXT"))
.addColumn(new Column(PASSWORD_COLUMN, "TEXT"))
.doneTableColumn();
mainAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String name = mainName.getText().toString();
String password = mainPassword.getText().toString();
boolean done = easyDB.addData(1, name)
.addData(2, password)
.doneDataAdding();
if (done) {
Toast.makeText(MainActivity.this, "User added successfully", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "User not added", Toast.LENGTH_SHORT).show();
}
}
});
mainRead.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
/*
Cursor cursor = easyDB.getAllData();
while (cursor.moveToNext()) {
String name = cursor.getString(1);
String password = cursor.getString(2);
Toast.makeText(MainActivity.this, name + "\n" + password, Toast.LENGTH_SHORT).show();
}
*/
startActivity(new Intent(MainActivity.this, UsersActivity.class));
}
});
Any help please?
You have to prepare the user list from the DB cursor and use it to RecyclerView. Check below:
List<User> userList = new ArrayList<>();
EasyDB easyDB = EasyDB.init(this, DATABASE_NAME).setTableName(TABLE_NAME);
Cursor res = easyDB.getAllData();
if(res != null && res.getCount() > 0) {
res.moveToFirst();
do {
int id = res.getInt(0);
String name = res.getString(1);
String pass = res.getString(2);
userList.add(new User(id, name, pass));
} while (res.moveToNext());
}
res.close();
RecyclerView recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
UsersRecyclerAdapater adapter = new UsersRecyclerAdapater(this, userList);
recyclerView.setAdapter(adapter);
You will have to iterate through the cursor and create a List out of it and your RecyclerView will take that list as input.
List<User> userList = new ArrayList<>();
if (cursor.moveToFirst()) {
do {
int anIntegerVariable = cursor.getInt(columnIndex);
String aStringVariable = cursor.getString(columnIndex);
User user = new User();
user.setId(anIntegerVariable();
user.setName(aStringVariable);
userList.add(user);
} while (cursor.moveToNext());
}
cursor.close();
You should have a look at Room which is the recommended database library for android applications. https://developer.android.com/training/data-storage/room

How to update total no of child from firebase child node everytime onDataChange from AddSingleValueEventListner?

Below image shows my Firebase database structure:
All data retrieved successfully. Here is my model class.
public class Post
{
public String lastname;
public String postid;
public long timestamp;
public HashMap<String,Boolean> count;
public Post()
{
}
public Post(String lastname, long timestamp, String postid,HashMap count)
{
this.lastname=lastname;
this.timestamp=timestamp;
this.postid=postid;
this.count=count;
}
public HashMap<String, Boolean> getCounts() {
return count;
}
public void setCounts(HashMap<String, Boolean> count) {
this.count = count;
}
In Main Activity i used to get data
mAdapter = new PostAdapter(MainActivity.this);
getAllPost(null);
postList.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (!recyclerView.canScrollVertically(1))
{
loaded=loaded+10;
if (totalPost== mAdapter.getItemCount())
{
Toast.makeText(MainActivity.this, "no more post", Toast.LENGTH_SHORT).show();
}
else
{
getAllPost(mAdapter.getLastItemId());
}
}
}
});
postList.setAdapter(mAdapter);
private void getAllPost(final String nodeId)
{
final Query query;
final int left= (int) (totalPost-mAdapter.getItemCount());
Toast.makeText(this, String .valueOf(left), Toast.LENGTH_SHORT).show();
if (nodeId == null)
{
query = PostRef
.orderByChild("timestamp")
.limitToLast(mPostsPerPage);
}
else
{
if (left<10)
{
query = PostRef
.orderByChild("timestamp")
.limitToFirst(left);
}
else
{
Long time=Long.parseLong(nodeId);
query = PostRef
.orderByChild("timestamp").endAt(time)
.limitToLast(10);
}
}
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<Post> userModels = new ArrayList<>();
for (DataSnapshot userSnapshot : dataSnapshot.getChildren())
{
userModels.add(userSnapshot.getValue(Post.class));
}
if (!(nodeId ==null))
{
if (left>10)
{
userModels.remove(9);
}
}
Collections.reverse(userModels);
mAdapter.addAll(userModels);
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
});
}
And in adapter:
public class PostAdapter extends RecyclerView.Adapter<PostHolder>
{
List<Post> mPost;
Context mContext;
public PostAdapter(Context c) {
this.mPost = new ArrayList<>();
mContext=c;
}
#NonNull
#Override
public PostHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
return new PostHolder(LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.all_post_layout, viewGroup, false));
}
#Override
public void onBindViewHolder(#NonNull final PostHolder postHolder, final int i) {
final String PostKey=mPost.get(i).getPostid();
FirebaseAuth mAuth=FirebaseAuth.getInstance();
final String currentUserID=mAuth.getCurrentUser().getUid();
final DatabaseReference post=FirebaseDatabase.getInstance().getReference().child("Posts");
showCounts(postHolder,i);
setCountsButton(postHolder,i,currentUserID);
tapOnCounts(postHolder,i,currentUserID,post,PostKey);
}
private void tapOncounts(final PostHolder postHolder, final int i, final String currentUserID, final DatabaseReference post, final String postKey)
{
postHolder.countsButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v)
{
if (mPost.get(i).getCounts() !=null)
{
if(mPost.get(i).getCounts().containsKey(currentUserID))
{
post.child(postKey).child("counts").child(currentUserID).removeValue();
postHolder.countsButton.setImageResource(R.drawable.discounts);
}
else
{
postHolder.countsButton.setImageResource(R.drawable.counts);
post.child(postKey).child("counts").child(currentUserID).setValue(true);
}
}
else
{
postHolder.countsButton.setImageResource(R.drawable.counts);
post.child(postKey).child("counts").child(currentUserID).setValue(true);
}
}
});
}
private void setcountsButton(final PostHolder postHolder, int i, String currentUserID)
{
if (mPost.get(i).getCounts() !=null)
{
if(mPost.get(i).getCounts().containsKey(currentUserID))
{
postHolder.countsButton.setImageResource(R.drawable.counts);
}
else
{
postHolder.countsButton.setImageResource(R.drawable.discounts);
}
}
}
private void showCounts(PostHolder postHolder, int i)
{
if((mPost.get(i).getCounts() !=null))
{
postHolder.noOfcounts.setText(String.valueOf(mPost.get(i).getCounts().size()));
}
else
{
postHolder.noOfcounts.setText("0");
}
}
#Override
public int getItemCount() {
return mPost.size();
}
public void addAll(List<Post> newPost) {
int initialSize = mPost.size();
mPost.addAll(newPost);
notifyItemRangeInserted(initialSize, newPost.size());
}
public String getLastItemId() {
return String.valueOf(mPost.get(mPost.size() - 1).getTimestamp());
}
}
All is successfully but whenever total no. of child change(new child added OR old child removed) in count node recylerview is not update. It will only update when i tried to go another activity and come to rerun in MainActivity.
To get realtime updates, you should use Query's addValueEventListener(ValueEventListener listener) method:
Add a listener for changes in the data at this location.
When using addListenerForSingleValueEvent(ValueEventListener listener):
Add a listener for a single change in the data at this location.
Edit:
To get the size of your list, please change the following line of code:
holder.count.setText(String.valueOf(mPost.get(i).getCount().size));
to
holder.count.setText(String.valueOf(getItemCount());
Whenever total number of child changes then your list of Post modal also changes i.e. userModels in your case. Hence whenever your list of model changes your adapter needs to be notified. Hence my guess is to add notifyDataSetChanged to adapter.
Try this:
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<Post> userModels = new ArrayList<>();
for (DataSnapshot userSnapshot : dataSnapshot.getChildren()) {
userModels.add(userSnapshot.getValue(Post.class));
}
mAdapter.notifyDataSetChanged(); //<<changes made HERE
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
})
For this to work I hope userModels is instance variable to your MainActivity and is set to mAdapter during initialization.

not able to display inner child nodes value in recycler view

before down voting please consider this i have searched everywhere and not found the solution please help..
from the above structure i want to access the values inside Results -> examId> total_marks, marks_scored but i am not being able to get inside Result node
i want the values to be feed inside recyclerview
This is my adapter
public class MarksListAdapter extends RecyclerView.Adapter<MarksListAdapter.MyViewHolder> {
Context context;
ArrayList<MarksList> marksListArrayList;
public MarksListAdapter(Context c, ArrayList<MarksList> p) {
context = c;
marksListArrayList = p;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
return new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.marks_list, viewGroup, false));
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder myViewHolder, int i) {
myViewHolder.tvStudentName.setText(marksListArrayList.get(i).getName());
myViewHolder.tvOutOf_List.setText(marksListArrayList.get(i).getResults().getTotal_marks());
myViewHolder.etEnterMarks.setText(marksListArrayList.get(i).getResults().getMarks_scored());
POJO class
public class MarksList {
String name;
public MarksList() {
}
public MarksList(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private Results Results;
public com.hitech.hitechacademy.POJO.Results getResults() {
return Results;
}
}
public class Results {
String marks_scored;
String total_marks;
public Results() {
}
public Results(String marks_scored, String total_marks) {
this.marks_scored = marks_scored;
this.total_marks = total_marks;
}
public String getMarks_scored() {
return marks_scored;
}
public void setMarks_scored(String marks_scored) {
this.marks_scored = marks_scored;
}
public String getTotal_marks() {
return total_marks;
}
public void setTotal_marks(String total_marks) {
this.total_marks = total_marks;
}
}
both are seperate java classes
This is the recyclerview activity
DatabaseReference examRef = firebaseDatabase.getReference().child("Batches").child(batchNameValue);
examRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String examTitle;
String studentName;
specificStudent.clear();
resultsArrayList.clear();
for (DataSnapshot studentResult : dataSnapshot.getChildren()) {
examTitle = (String) studentResult.child("Results").child(examKeyValue).child("exam_name").getValue();
Log.d("TAG_Full", examTitle + "" + examFullName);
if (examTitle != null && examTitle.equals(examFullName)) {
MarksList marksList = studentResult.getValue(MarksList.class);
//studentName = (String) studentResult.child("name").getValue();
specificStudent.add(marksList);
Log.d("SpecificStudent", specificStudent.toString() + resultsArrayList.toString());
} else {
//code for 1 exam and no students
}
}
specificStudent.toString();
marksListAdapter = new MarksListAdapter(LoadedExam.this,specificStudent);
marksRecyclerView.setAdapter(marksListAdapter);
marksListAdapter.notifyDataSetChanged();
}
I am not getting any errors but only the name of the student is getting fetched Please help

Upload data to firebase through a java class and retrieve one attribute in another activity

Firebase Database LinkI am trying to save data to firebase using this code.
Everything works fine. I was saving the data creating new children uder users>uid. but now when i try to save the data by creating an object and passing that object in setvalue, the app crashes. Please help.
public class RegComplete extends AppCompatActivity {
private EditText Name, Surname, Address, Tel, DateOfBirth,Username;
private String _name, _surname, _address, _Tel, _DateOfBirth,_UserName, email;
public String uid = "";
FirebaseDatabase database = FirebaseDatabase.getInstance();
private DatabaseReference mdatabase;
private DatabaseReference fdatabase;
FirebaseAuth auth = FirebaseAuth.getInstance();
FirebaseUser objuser = auth.getCurrentUser();
List<String> lstSports = new ArrayList<String>();
List<String> lstSteden = new ArrayList<String>();
String strSport1,strSport2,strSport3;
public String strCity;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reg_complete);
fdatabase = database.getReference();
fdatabase.child("Steden").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot DS:dataSnapshot.getChildren()) {
String CityName = DS.child("CityName").getValue(String.class);
City stad = new City(CityName);
lstSteden.add(stad.CityName);
}
final Spinner CitySpin = (Spinner) findViewById(R.id.CitySpin);
ArrayAdapter<String> CityAdapter = new ArrayAdapter<String>(RegComplete.this, android.R.layout.simple_spinner_item, lstSteden);
CityAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
CitySpin.setAdapter(CityAdapter);
CitySpin.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
strCity = CitySpin.getSelectedItem().toString();
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
fdatabase.child("SPORTS").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot ds :dataSnapshot.getChildren()) {
String sportName = ds.child("SportName").getValue(String.class);
Sport objsport = new Sport(sportName);
lstSports.add(objsport.SportName);
}
final Spinner Sports1 = (Spinner) findViewById(R.id.SportSpinner1);
ArrayAdapter<String> SportAdapter = new ArrayAdapter<String>(RegComplete.this, android.R.layout.simple_spinner_item, lstSports);
SportAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
Sports1.setAdapter(SportAdapter);
Sports1.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
strSport1 = Sports1.getSelectedItem().toString();
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
final Spinner Sports2 = (Spinner) findViewById(R.id.SportSpinner2);
Sports2.setAdapter(SportAdapter);
Sports2.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
strSport2 = Sports2.getSelectedItem().toString();
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
final Spinner Sports3 = (Spinner) findViewById(R.id.SportSpinner3);
Sports3.setAdapter(SportAdapter);
Sports3.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
strSport3 = Sports3.getSelectedItem().toString();
}
#Override
public void onNothingSelected(AdapterView<?> adapterView) {
}
});
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Name = findViewById(R.id.NameeditText);
_name = Name.getText().toString();
Surname = findViewById(R.id.SurnameEditText);
_surname = Surname.getText().toString();
Address = findViewById(R.id.AdressEditText);
_address = Address.getText().toString();
Tel = findViewById(R.id.TelEditText);
_Tel = Tel.getText().toString();
DateOfBirth = findViewById(R.id.DOBEditText);
_DateOfBirth = DateOfBirth.getText().toString();
Username = findViewById(R.id.UserIDEditText);
_UserName = Username.getText().toString();
email = FirebaseAuth.getInstance().getCurrentUser().getEmail().toString();
}
public void btnSave_Click(View V){
User usinfo = new User(email,_UserName,_name,_surname,_address,strCity,_Tel,_DateOfBirth,strSport1,strSport2,strSport3,uid);
mdatabase = FirebaseDatabase.getInstance().getReference("USERS");
uid = objuser.getUid();
mdatabase.child(uid).setValue(usinfo);
Intent i = new Intent(RegComplete.this, LoginActivity.class);
Toast.makeText(RegComplete.this ,"Registration Complete" ,Toast.LENGTH_SHORT).show();
startActivity(i);
}
}
The code for USER.class
public class User {
public String Email;
public String UserName;
public String Name;
public String SurName;
public String StreetAdress;
public String City;
public String Tel;
public String DOB;
public String Sport1;
public String Sport2;
public String Sport3;
public String UserId;
public User(){
// Default constructor required by Firebase
}
public User(String email, String userName, String name, String surName, String streetAdress, String city, String tel, String DOB, String sport1, String sport2, String sport3, String userId) {
Email = email;
UserName = userName;
Name = name;
SurName = surName;
StreetAdress = streetAdress;
City = city;
Tel = tel;
this.DOB = DOB;
Sport1 = sport1;
Sport2 = sport2;
Sport3 = sport3;
UserId = userId;
}
public String getEmail() {
return Email;
}
public String getUserName() {
return UserName;
}
public String getName() {
return Name;
}
public String getSurName() {
return SurName;
}
public String getStreetAdress() {
return StreetAdress;
}
public String getCity() {
return City;
}
public String getTel() {
return Tel;
}
public String getDOB() {
return DOB;
}
public String getSport1() {
return Sport1;
}
public String getSport2() {
return Sport2;
}
public String getSport3() {
return Sport3;
}
public String getUserId() {
return UserId;
}
}
And i am also trying to retrieve UserName for the user with which i am signed in in another activity.
using this code.
mdatabase.child("USERS").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
userinf = ds.child(uid).getValue(User.class);
};
txtUserNaam.setText(userinf.UserName);
}
Where
DatabaseReference mdatabase = FirebaseDatabase.getInstance().getReference();
Please help
Firebase is getting confused between this field:
public String City;
And this getter:
public String getCity() {
return City;
}
The field defines a property City, while the getter defines a property city. As you can see the case is different between the two, which leads to the error message.
The easiest fix is to mark all your fields as private:
private String City;
This keeps Firebase from considering them while reading/writing users.

Android retrieving data from Firebase doesn't work for data models even it works for other data model in the project with similar codes

I am new in Android and working on an Android app which can retrieve data from firebase. There is a weird problem. I already successfully implemented the retrieving function for one data model of my program, and I used same codes just changed the variables but it doesn't work for another data model. I did many tests and I think the problem is in FirebaseHelper cuz there is no any data returned from the data snapshot. The error is
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
The codes are shown below:
The Activity that shows the retrieved data in a listview.
public class TimeTableActivity extends AppCompatActivity {
DatabaseReference db;
FirebaseHelper firebasehelper;
TimeTableAdapter adapter;
ListView lv_CourseList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_time_table);
//GET INTENT
Intent intent = this.getIntent();
String majorID = intent.getStringExtra("MAJOR_ID");
lv_CourseList = (ListView) findViewById(R.id.lv_CourseList);
//INITIALIZE FIREBASE DB
db= FirebaseDatabase.getInstance().getReference();
firebasehelper=new FirebaseHelper(db);
//ADAPTER
adapter = new TimeTableAdapter(getApplicationContext(),firebasehelper.retrieveCourse(majorID, new CourseCallbacks() {
#Override
public void onCourseCallback(ArrayList<CourseInfo> courseInfos) {
lv_CourseList.setAdapter(adapter);
}
}));
lv_CourseList.setAdapter(adapter);
}
}
FirebaseHelper:
public class FirebaseHelper{
private DatabaseReference db;
private ArrayList<Major> majors = new ArrayList<>();
private ArrayList<CourseInfo> courseInfos = new ArrayList<>();
public FirebaseHelper(DatabaseReference db) {
this.db = db;
}
//Save the Major info. into db
public Boolean saveMajor(Major major)
{
Boolean saved = null;
if(major==null)
{
saved =false;
}else
{
try
{
db.child("Major").push().setValue(major);
saved =true;
}catch (DatabaseException e)
{
e.printStackTrace();
saved =false;
}
}
return saved;
}
//Save the Course info. into db
public Boolean saveCourse(CourseInfo courseInfo)
{
Boolean saved = null;
if(courseInfo==null)
{
saved =false;
}else
{
try
{
db.child("CourseInfo").push().setValue(courseInfo);
saved =true;
}catch (DatabaseException e)
{
e.printStackTrace();
saved =false;
}
}
return saved;
}
public ArrayList<Major> retrieveMajor(final MajorCallbacks majorCallbacks){
ChildEventListener childEventListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
Major major = ds.getValue(Major.class);
if (major != null && major.getMajor_id() != null) {
majors.add(major);
}
}
majorCallbacks.onMajorCallback(majors);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
Major major = ds.getValue(Major.class);
if (major != null && major.getMajor_id() != null) {
majors.add(major);
}
}
majorCallbacks.onMajorCallback(majors);
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
db.addChildEventListener(childEventListener);
if (!majors.isEmpty()){
db.removeEventListener(childEventListener);
}
return majors;
}
public ArrayList<CourseInfo> retrieveCourse(String majorID, final CourseCallbacks courseCallbacks){
ChildEventListener childEventListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String prevChildKey) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
CourseInfo courseInfo = ds.getValue(CourseInfo.class);
if (courseInfo != null && courseInfo.getCourse_id() != null) {
courseInfos.add(courseInfo);
}
}
courseCallbacks.onCourseCallback(courseInfos);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String prevChildKey) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
CourseInfo courseInfo = ds.getValue(CourseInfo.class);
if (courseInfo != null && courseInfo.getCourse_id() != null) {
courseInfos.add(courseInfo);
}
}
courseCallbacks.onCourseCallback(courseInfos);
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String prevChildKey) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
db.child("CourseInfo").orderByChild("major_id").equalTo(majorID).addChildEventListener(childEventListener);
return courseInfos;
}
}
The retrieveMajor method works well even though it returns many null data and repetitive data, and I used the codes of retrieveMajor in retrieveCourse. It doesn't work, the courseInfos is always null. Even though I changed db.child("CourseInfo").orderByChild("major_id").equalTo(majorID).addChildEventListener(childEventListener);
to
db.addChildEventListener(childEventListener);
,still nothing is retrieved which means the problem is not the query (Probably the query is also wrong).
Adapter:
public class TimeTableAdapter extends BaseAdapter {
Context context;
ArrayList<CourseInfo> courseInfos;
public TimeTableAdapter(Context context, ArrayList<CourseInfo> courseInfos) {
this.context = context;
this.courseInfos = courseInfos;
}
#Override
public int getCount() {
return courseInfos.size();
}
#Override
public Object getItem(int pos) {
return courseInfos.get(pos);
}
#Override
public long getItemId(int pos) {
return pos;
}
#Override
public View getView(int position, View convertView, ViewGroup viewGroup) {
LayoutInflater inflater = LayoutInflater.from(context);
if(convertView == null)
{
convertView= LayoutInflater.from(context).inflate(R.layout.model_timetable,viewGroup,false);
}
TextView tv_courseid= (TextView) convertView.findViewById(R.id.tv_courseid);
TextView tv_coursename= (TextView) convertView.findViewById(R.id.tv_coursename);
TextView tv_courseinstructor= (TextView) convertView.findViewById(R.id.tv_courseinstructor);
TextView tv_courseavailable= (TextView) convertView.findViewById(R.id.tv_courseavailable);
final CourseInfo courseInfo= (CourseInfo) this.getItem(position);
tv_courseid.setText(courseInfo.getCourse_id());
tv_coursename.setText(courseInfo.getCourse_name());
tv_courseinstructor.setText(courseInfo.getCourse_instructor());
tv_courseavailable.setText(courseInfo.getCourse_available());
return convertView;
}
}
Data model:
#IgnoreExtraProperties
public class CourseInfo {
public String course_id;
public String course_name;
public int course_section;
public String course_type;
public double course_crdhrs;
public String course_days;
public String course_times;
public String course_location;
public int course_max;
public int course_cur;
public int course_available;
public int course_wl;
public double course_per;
public String course_instructor;
public String course_description;
public String course_prerequire;
public String major_id;
public CourseInfo() {
}
public CourseInfo(String course_id, String course_name, int course_section, String course_type, double course_crdhrs, String course_days, String course_times, String course_location, int course_max, int course_cur, int course_available, int course_wl, double course_per, String course_instructor, String course_description, String course_prerequire, String major_id) {
this.course_id = course_id;
this.course_name = course_name;
this.course_section = course_section;
this.course_type = course_type;
this.course_crdhrs = course_crdhrs;
this.course_days = course_days;
this.course_times = course_times;
this.course_location = course_location;
this.course_max = course_max;
this.course_cur = course_cur;
this.course_available = course_available;
this.course_wl = course_wl;
this.course_per = course_per;
this.course_instructor = course_instructor;
this.course_description = course_description;
this.course_prerequire = course_prerequire;
this.major_id = major_id;
}
public String getCourse_id() {
return course_id;
}
public String getCourse_name() {
return course_name;
}
public int getCourse_section() {
return course_section;
}
public String getCourse_type() {
return course_type;
}
public double getCourse_crdhrs() {
return course_crdhrs;
}
public String getCourse_days() {
return course_days;
}
public String getCourse_times() {
return course_times;
}
public String getCourse_location() {
return course_location;
}
public int getCourse_max() {
return course_max;
}
public int getCourse_cur() {
return course_cur;
}
public int getCourse_available() {
return course_available;
}
public int getCourse_wl() {
return course_wl;
}
public double getCourse_per() {
return course_per;
}
public String getCourse_instructor() {
return course_instructor;
}
public String getCourse_description() {
return course_description;
}
public String getCourse_prerequire() {
return course_prerequire;
}
public String getMajor_id() {
return major_id;
}
}
If you need more codes or information, please comment and let me know. I will really appreciate if you can also help me solve the null data and repetitive data problem cuz it makes the listview show many blank and repetitive items.
You cannot return something now that hasn't been loaded yet. With other words, you cannot just simply create a method that as a return type, an ArrayList<Major> and in the same time return that object. This is happening because those methods, onChildAdded(), onChildChanged() and so on, have an asynchronous behaviour, which means that are called even before you are getting/updating the data from/in the database. To solve this, you can move the declaration of that ArrayList inside one method and do what you need to do with it or dive into asynchronous world and use the last part of my answer from this post. You can take also a look at this video for a better understanding.

Categories