How to properly initialize value from firebase with model class - java

I am making a firebase app where the user is able to rate another user. I am occasionally getting a null pointer on this like of code:
averageStars+=Double.parseDouble(rate.getRates());
I seem to mess things up like this often, where I create a model class and then somehow never initialize it. However, even with some research, I am not sure why these are not considered initialized. Would anyone have an idea on how I initialize classes like this(Firebase). My main code for the activity looks like:
public class RateActivity extends AppCompatActivity {
Button btnSubmit;
MaterialRatingBar ratingBar;
MaterialEditText edtComment;
FirebaseDatabase database;
DatabaseReference rateDetailRef;
DatabaseReference driverInformationRef;
double ratingStars= 0.0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rate);
database = FirebaseDatabase.getInstance();
rateDetailRef = database.getReference(Common.rate_detail_tbl);
driverInformationRef = database.getReference(Common.user_driver_tbl);
btnSubmit = (Button)findViewById(R.id.btnSumbit);
ratingBar = (MaterialRatingBar)findViewById(R.id.ratingBar);
edtComment = (MaterialEditText)findViewById(R.id.edtComment);
ratingBar.setOnRatingChangeListener(new MaterialRatingBar.OnRatingChangeListener() {
#Override
public void onRatingChanged(MaterialRatingBar ratingBar, float rating) {
ratingStars = rating;
}
});
btnSubmit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
submitRateDetails(Common.driverId);
}
});
}
private void submitRateDetails(String driverId) {
SpotsDialog alertDialog = new SpotsDialog(this);
alertDialog.show();
Rate rate = new Rate();
rate.setRates(String.valueOf(ratingStars));
rate.setComments(edtComment.getText().toString());
rateDetailRef.child(Common.driverId)
.child(FirebaseAuth.getInstance().getCurrentUser().getUid())
.push()
.setValue(rate)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
rateDetailRef.child(Common.driverId)
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
double averageStars = 0.0;
int count = 0;
for(DataSnapshot postSnapshot : dataSnapshot.getChildren())
{
Rate rate = postSnapshot.getValue(Rate.class);
averageStars+=Double.parseDouble(rate.getRates());
count++;
}
double finalAverage = averageStars/count;
DecimalFormat df = new DecimalFormat("#.#");
String valueUpdate = df.format(finalAverage);
Map<String,Object> driverUpdateRate = new HashMap<>();
driverUpdateRate.put("rates",valueUpdate);
driverInformationRef.child(Common.driverId)
.updateChildren(driverUpdateRate)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
alertDialog.dismiss();
Toast.makeText(RateActivity.this, "Thank you for your feedback", Toast.LENGTH_SHORT).show();
finish();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
alertDialog.dismiss();
Toast.makeText(RateActivity.this, "Rating did not go through", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
alertDialog.dismiss();
Toast.makeText(RateActivity.this,"Rating failed?",Toast.LENGTH_SHORT).show();
}
});
}
}
My model class for the "getRates" feature looks like
public class Rate {
private String rates;
private String comments;
public Rate(String rates, String comments) {
this.rates = rates;
this.comments = comments;
}
public Rate(){}
public String getRates() {
return rates;
}
public void setRates(String rates) {
this.rates = rates;
}
public String getComments() {
return comments;
}
public void setComments(String comments) {
this.comments = comments;
}
}
Thank you.
Due to request, here is my logcat:
2020-01-26 17:59:25.792 25184-25184/com.example.usubx E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.usubx, PID: 25184
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.trim()' on a null object reference
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1838)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:538)
at com.example.usubx.RateActivity$4$1.onDataChange(RateActivity.java:102)
at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database##19.2.0:75)
at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database##19.2.0:63)
at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database##19.2.0:55)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Here is the value of my datasnapshot
DataSnapshot { key = RateDetails, value = {UE7cSOf5Thbum6OwEmg9seAPD463={-LzZH15-YVs1m67EuJlD={comments=Colin, rates=4.5}, -LzZHvuClxb5Ef3jk23_={comments=, rates=5.0}}, -LzJrTz5FrzEaoWorqP-={comments=, rates=5.0}, -LzKQn7F1ybKVAxUj9NX={comments=heck cool, rates=5.0}, -LzNyBwBh0tVHKvMfgEk={comments=, rates=5.0}, vAdqbIhLKJasOtyXKYrCkrOSVq33={-Lz-hH6TXxKTUVvIUYnK={comments=he was cool, rates=5.0}, -LzNz80QZDhnZA1tJ27Y={comments=, rates=3.5}, -Lz-h35N3l0xnLVVNvwa={comments=, rates=1.5}, -LzJqTWwUXOsfKPDZh2E={comments=, rates=5.0}, -LzNzEjdyg_aYMAfdI14={comments=, rates=5.0}, -LzJomtnZH4zJ6nddk0c={comments=HECK YES IT WORKS, rates=5.0}}, -LzJt7VA3iVPLopRFD34={comments=let's go, rates=5.0}, -LzNxj1zaWAZukLPyTEw={comments=, rates=5.0}, -LzNv9bTAz7_3vXioMRe={comments=heck, rates=5.0}} }

I agree with the other answer that, just putting a null should suffice to handle the case here. However, from your question, it looks like you want to initialize the Rate class with default values so that you do not end up with some invalid/null values at any point in time. In that case, I would actually suggest modifying the Rate class getters as follows.
public class Rate {
private String rates;
private String comments;
public Rate(String rates, String comments) {
this.rates = rates;
this.comments = comments;
}
public Rate(){}
public String getRates() {
if (rates == null) return "0.0";
else return rates;
}
public void setRates(String rates) {
this.rates = rates;
}
public String getComments() {
if (comments == null) return ""; // Return empty string
else return comments;
}
public void setComments(String comments) {
this.comments = comments;
}
}
I hope that helps!

Because your database has null rates. Please check your database. some data did not have rates string.
and check null like this to avoid NullPointerException
if(rate.getRates() != null)
averageStars+=Double.parseDouble(rate.getRates());

Related

How to Sort the List<Model> data after fetching Android

I am fetching data and adding it to List from firebase database.
Now i want to sort the list data based on time so that latest data will appear first on the list and then setting the updated list into my RecyclerView.Adapter. I have tried layoutmanager.setReverseLayout(true); and layoutmanager.setStackFromEnd(true); for reversing the RecyclerView but it always shows data from the middle and also I don't want to follow this method.
How can i do that.
public class HistoryActivity extends AppCompatActivity{
private String customerOrDriver, userId;
private String doctorId, patientId, pharmacyId, userDriverOrCustomer;
private Long timestamp;
private String name, service;
private SwipeRefreshLayout swipeRefreshLayout;
private RecyclerView mHistoryRecyclerView;
private RecyclerView.Adapter mHistoryAdapter;
private RecyclerView.LayoutManager mHistoryLayoutManager;
SharedPreferences sharedPreferences;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_history);
customerOrDriver = getIntent().getExtras().getString("customerOrDriver");
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(HistoryActivity.this);
userId = sharedPreferences.getString("UID","");
mHistoryRecyclerView = (RecyclerView) findViewById(R.id.historyRecyclerView);
mHistoryAdapter = new HistoryAdapter(getDataSetHistory(), HistoryActivity.this);
mHistoryLayoutManager = new LinearLayoutManager(HistoryActivity.this);
mHistoryRecyclerView.setLayoutManager(mHistoryLayoutManager);
mHistoryRecyclerView.setHasFixedSize(true);
/*// sort the recycler view to descending order
((LinearLayoutManager) mHistoryLayoutManager).setReverseLayout(true);
((LinearLayoutManager) mHistoryLayoutManager).setStackFromEnd(true);*/
mHistoryRecyclerView.setItemAnimator(new DefaultItemAnimator());
mHistoryRecyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
mHistoryRecyclerView.setAdapter(mHistoryAdapter);
getUserHistoryIds();
}
private void getUserHistoryIds() {
//swipeRefreshLayout.setRefreshing(true);
DatabaseReference userHistoryDatabase = FirebaseDatabase.getInstance().getReference().child(Common.user_table).child(customerOrDriver).child(userId).child(Common.history_table);
userHistoryDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
for(DataSnapshot history : dataSnapshot.getChildren()){
FetchRideInformation(history.getKey());
//swipeRefreshLayout.setRefreshing(false);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
//swipeRefreshLayout.setRefreshing(false);
}
});
}
private void FetchRideInformation(String rideKey) {
DatabaseReference historyDatabase = FirebaseDatabase.getInstance().getReference().child(Common.history_table).child(rideKey);
historyDatabase.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
String rideId = dataSnapshot.getKey();
timestamp = 0L;
for(DataSnapshot child : dataSnapshot.getChildren()){
if (child.getKey().equals("timestamp")){
timestamp = Long.valueOf(child.getValue().toString());
}
}
getRideInformation(rideId, timestamp);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private void getRideInformation(final String rideId, final Long timestamp) {
DatabaseReference historyRideInfoDb = FirebaseDatabase.getInstance().getReference().child(Common.history_table).child(rideId);
historyRideInfoDb.addListenerForSingleValueEvent(new ValueEventListener() {
#SuppressLint("SetTextI18n")
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
for (DataSnapshot child : dataSnapshot.getChildren()) {
if (child.getKey().equals("patient")) {
patientId = child.getValue().toString();
if (!patientId.equals(userId)) {
userDriverOrCustomer = "Doctors";
getUserInformation("Patients", patientId, rideId, timestamp);
}
}
else if (child.getKey().equals("patient")) {
patientId = child.getValue().toString();
if (!patientId.equals(userId)) {
userDriverOrCustomer = "Phamacys";
getUserInformation("Patients", patientId, rideId, timestamp);
}
}
if (child.getKey().equals("doctor")) {
doctorId = child.getValue().toString();
if (!doctorId.equals(userId)) {
userDriverOrCustomer = "Patients";
getUserInformation("Doctors", doctorId, rideId, timestamp);
}
}
else if (child.getKey().equals("pharmacy")) {
pharmacyId = child.getValue().toString();
if (!pharmacyId.equals(userId)) {
userDriverOrCustomer = "Patients";
getUserInformation("Pharmacys", pharmacyId, rideId, timestamp);
}
}
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private void getUserInformation(String otherUserDriverOrCustomer, String otherUserId, final String rideId, final Long timestamp) {
DatabaseReference mOtherUserDB = FirebaseDatabase.getInstance().getReference().child(Common.user_table).child(otherUserDriverOrCustomer).child(otherUserId);
mOtherUserDB.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
Map<String, Object> map = (Map<String, Object>) dataSnapshot.getValue();
if (map.get("name") != null) {
name = (map.get("name").toString());
}
if(map.get("service") == null)
{
service = (map.get("phone").toString());
}
else if (map.get("service") != null) {
service = (map.get("service").toString());
}
HistoryObject obj = new HistoryObject(rideId, name, service, getDate(timestamp));
resultsHistory.add(obj);
mHistoryAdapter.notifyDataSetChanged();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
private String getDate(Long time) {
Calendar cal = Calendar.getInstance(Locale.getDefault());
cal.setTimeInMillis(time*1000);
String date = DateFormat.format("MMMM dd yyyy, hh:mm a", cal).toString();
return date;
}
private ArrayList resultsHistory = new ArrayList<HistoryObject>();
private ArrayList<HistoryObject> getDataSetHistory() {
return resultsHistory;
}
}
Simply use myList.sort() then read it the way its needed like ascending or descending amd put it in the RecyclerView
You can sort your by following way
Her i just showed you an Student object but in your case you can check with datetime
Using Lambda expression: The Java 8 equivalent code using Lambda expression would look like this:
studentlist.sort((Student s1, Student s2)->s1.getName().compareTo(s2.getName()));

How to retrieved data in Firebase to the Android Studio [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I need to retrieved data from database Firebase. But I have problem since when I try to retrieve the data, the application will stop.
this is the code for retrievedPoint.java
final FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference ref = database.getReference("reloadPoint");
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
ReloadPoint rp = dataSnapshot.getValue(ReloadPoint.class);
System.out.println(rp);
}
#Override
public void onCancelled(DatabaseError databaseError) {
System.out.println("The read failed: " + databaseError.getCode());
}
});
ref.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
ReloadPoint newPost = dataSnapshot.getValue(ReloadPoint.class);
System.out.println("Email: " + newPost.getmEmail());
System.out.println("Point: " + newPost.getmPoint());
System.out.println("User id: " + newPost.getmUserid());
}
#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) {
}
});
this the code for the ReloadPoint class.
public class ReloadPoint {
private String mEmail;
private String mPoint;
private String mUserid;
public ReloadPoint(String email, String point, String userid) {
this.mEmail = email;
this.mPoint = point;
this.mUserid = userid;
}
public String getmEmail() {
return mEmail;
}
public void setmEmail(String mEmail) {
this.mEmail = mEmail;
}
public String getmPoint() {
return mPoint;
}
public void setmPoint(String mPoint) {
this.mPoint = mPoint;
}
public String getmUserid() {
return mUserid;
}
public void setmUserid(String mUserid) {
this.mUserid = mUserid;
}
}
This is the thing that I want to retrieve from Firebase.
this is the child that I want to retrieve
This is the Android where the retrived data will appear if the retrieved process is success.retrievedPoint.xml
Result from log cat.Log cat result
Please help me.
As the error message implies, your ReloadPoint class needs a no-args constructor, e.g :
public ReloadPoint() {
}
Please include a no-argument constructor in your ReloadPoint class like so
public ReloadPoint() {
}
see this question users does not define no argument constructor
public class ReloadPoint {
private String mEmail;
private String mPoint;
private String mUserid;
//Ni hang lupa ni. apa la sakinah
//Klau da soklan lagi, hbungi kt insta id: nyrtron
public ReloadPoint(){
}
public ReloadPoint(String email, String point, String userid) {
this.mEmail = email;
this.mPoint = point;
this.mUserid = userid;
}
public String getmEmail() {
return mEmail;
}
public void setmEmail(String mEmail) {
this.mEmail = mEmail;
}
public String getmPoint() {
return mPoint;
}
public void setmPoint(String mPoint) {
this.mPoint = mPoint;
}
public String getmUserid() {
return mUserid;
}
public void setmUserid(String mUserid) {
this.mUserid = mUserid;
}
}
I think I have found your problem.
DatabaseReference ref = database.getReference().child("reloadPoint").child("Waniyanazahri");
UPDATED ANSWER:
Its look like you haven't call the class.
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
//Add this one
ReloadPoint rp = new ReloadPoint();
rp = dataSnapshot.getValue(ReloadPoint.class);
System.out.println(rp);
}
#Override
public void onCancelled(DatabaseError databaseError) {
System.out.println("The read failed: " + databaseError.getCode());
}
});

Android/FireStore QuerySnapshot convert to CustomObject

I am currently programin a test QuizApp. The gameplay is pretty easy I just want an online database of questions and a user can answer them.
This is what the database looks like:
That collection questions contains an unique ID and a custom Object (questionObject) named 'content'. The number is only something easy I can query/search for.
This is my questionAdder and query UI. It's only a small test App.
public class questionAdder extends AppCompatActivity {
EditText pQuestion, pAnwerA, pAnswerB, pAnswerC, pAnswerD, number;
Button pAdd, query;
private DatabaseReference databaseReference;
private FirebaseFirestore firebaseFirestore;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.addquestion);
firebaseFirestore = FirebaseFirestore.getInstance();
pQuestion = (EditText) findViewById(R.id.question);
pAnwerA = (EditText) findViewById(R.id.answerA);
pAnswerB = (EditText) findViewById(R.id.answerB);
pAnswerC = (EditText) findViewById(R.id.answerC);
pAnswerD = (EditText) findViewById(R.id.answerD);
number = (EditText) findViewById(R.id.number);
pAdd = (Button) findViewById(R.id.addQuestion);
pAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
readQuestionStore();
}
});
query = (Button) findViewById(R.id.query);
query.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
CollectionReference questionRef = firebaseFirestore.collection("questions");
questionRef.whereEqualTo("content.number", "20").get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
questionObject pContent = queryDocumentSnapshots.toObjects(questionObject.class);
}
});
}
});
}
public void readQuestionStore(){
Map<String, Object> pContent = new HashMap<>();
pContent.put("question", pQuestion.getText().toString());
pContent.put("Corr Answer", pAnwerA.getText().toString());
pContent.put("AnswerB", pAnswerB.getText().toString());
pContent.put("AnswerC", pAnswerC.getText().toString());
pContent.put("AnswerD", pAnswerD.getText().toString());
questionObject content = new questionObject(pContent, number.getText().toString()); //document("Essen").collection("Katalog")
firebaseFirestore.collection("questions").add(content).addOnSuccessListener(new OnSuccessListener<DocumentReference>() {
#Override
public void onSuccess(DocumentReference documentReference) {
Toast.makeText(questionAdder.this, "Klappt", Toast.LENGTH_LONG).show();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(questionAdder.this, "Klappt nicht", Toast.LENGTH_LONG).show();
}
});
}
}
And this is how my questionObject looks like:
public class questionObject{
private Map<String, Object> content;
private String number;
public questionObject(){
}
public questionObject(Map<String, Object> pContent, String pNumber) {
this.content = pContent;
this.number = pNumber;
}
public Map<String, Object> getContent() {
return content;
}
public void setContent(Map<String, Object> content) {
this.content = content;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
}
Problem In that questionAdder class in the onClickListener I receive an "incompatible types" Error (Found: java.utils.list Required: questionObject).
query.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
CollectionReference questionRef = firebaseFirestore.collection("questions");
questionRef.whereEqualTo("content.number", "20").get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
questionObject pContent = queryDocumentSnapshots.toObjects(questionObject.class);
}
});
}
});
If if I change that to a List it is empty. So the actual question is, how do I get the CustomObject into my code using the Database. Thanks!
The reason you are getting this error in because the QuerySnapshot is a type which "contains" multiple documents. Firestore won't decide for you whether there are a bunch of objects to return as a result, or just one.
This is why you can take two different approaches:
Put the data in a custom object's list:
List<questionObject> questionsList=new ArrayList<>();
if (!documentSnapshots.isEmpty()){
for (DocumentSnapshot snapshot:queryDocumentSnapshots)
questionsList.add(snapshot.toObject(questionObject.class));
}
If you're sure that your gonna get only one queried object, you can just get the first object from the returned queryDocumentSnapshots:
questionObject object=queryDocumentSnapshots.getDocuments().get(0).toObject(questionObject.class);
A few more things you should be aware of:
Why do you write content.number instead of just number?
It seems like number is a separated field in your question document, so your code should be as follows:
CollectionReference questionRef = firebaseFirestore.collection("questions");
questionRef.whereEqualTo("number", "20").get().addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
#Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
questionObject pContent = queryDocumentSnapshots.toObjects(questionObject.class);
}
});
In addition, try to change your number field to int, because it's not a String but a just a number.
By the way, it is more acceptable to write classes' names with a capital letter at a beginning, for example: QuestionObject question=new QuestionObject();

addChildEventListener is not working

In my app I want to add data to my Firebase database and read the data simultaneously. So I am using addChildEventListener() method to retrieve data. But this method is not working and the app is getting crashed everytime.
The code is given below:
public class ChatActivity extends AppCompatActivity {
LinearLayout layout;
RelativeLayout layout_2;
ImageView sendButton;
EditText messageArea;
ScrollView scrollView;
//Firebase reference1, reference2;
private DatabaseReference reference1, reference2,reference3;
private FirebaseAuth firebaseAuth;
private FirebaseUser firebaseUser;
private String username,userId;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
layout = (LinearLayout) findViewById(R.id.layout1);
layout_2 = (RelativeLayout)findViewById(R.id.layout2);
sendButton = (ImageView)findViewById(R.id.sendButton);
messageArea = (EditText)findViewById(R.id.messageArea);
scrollView = (ScrollView)findViewById(R.id.scrollView);
username=getIntent().getStringExtra("abc");
userId=getIntent().getStringExtra("abcd");
reference1= FirebaseDatabase.getInstance().getReferenceFromUrl("https://career-dna-bec2e.firebaseio.com/CHAT/user/" +username);
reference2=FirebaseDatabase.getInstance().getReferenceFromUrl("https://career-dna-bec2e.firebaseio.com/CHAT/admin/"+username);
sendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String messageText = messageArea.getText().toString();
if(!messageText.equals("")){
Map<String, String> map = new HashMap<String, String>();
map.put("message", messageText);
map.put("user",userId);
reference1.push().setValue(map);
reference2.push().setValue(map);
messageArea.setText("");
}
}
});
try
{
reference1.addChildEventListener(new com.google.firebase.database.ChildEventListener() {
#Override
public void onChildAdded(com.google.firebase.database.DataSnapshot dataSnapshot, String s) {
Map<String, String> map = dataSnapshot.getValue(Map.class);
String message = map.get("message").toString();
String userName = map.get("user").toString();
if(userName.equals(userId)){
addMessageBox("You:-\n" + message, 1);
}
else{
addMessageBox("admin"+ ":-\n" + message, 2);
}
}
#Override
public void onChildChanged(com.google.firebase.database.DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(com.google.firebase.database.DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(com.google.firebase.database.DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
catch (Exception e)
{
Toast.makeText(getApplicationContext(),"error:"+e,Toast.LENGTH_SHORT).show();
}
}
The app is crashing with this error:
02-23 20:43:15.832 12583-12583/com.ankush.anthroplace.careerdna
E/AndroidRuntime: FATAL EXCEPTION: main Process:
com.ankush.anthroplace.careerdna, PID: 12583
com.google.firebase.database.DatabaseException: Class java.util.Map
has generic type parameters, please use GenericTypeIndicator instead
Try using :
Map<String, Object> map = new HashMap<String, Object>();
While retrieving data use this :
Map<String, Object> map = dataSnapshot.getValue(Map.class);
But, if you really want to use Map class with 2 Strings as parameters, use this inside onChildAdded method :-
GenericTypeIndicator<Map<String, String>> genericTypeIndicator = new GenericTypeIndicator<Map<String, String>>() {};
Map<String, String> map = dataSnapshot.getValue(genericTypeIndicator);
There's no need to enter the full URL, use this instead
DatabaseReference reference1 = FirebaseDatabase.getInstance().getReference().child("CHAT").child("user").child(username);
DatabaseReference reference2 = FirebaseDatabase.getInstance().getReference().child("CHAT").child("admin").child(username);
And, one more thing you are doing wrong is, you are adding ChildEventListener everytime the sendButton is clicked, which is not neccesary, just create a ChildEventListener inside onCreate() and not in onClick() like this:-
ChildEventListener childEventListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Map<String, String> map = dataSnapshot.getValue(Map.class);
String message = map.get("message").toString();
String userName = map.get("user").toString();
if(userName.equals(userId)){
addMessageBox("You:-\n" + message, 1);
}
else{
addMessageBox("admin"+ ":-\n" + message, 2);
}
}
#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) {
Log.e("TAG", databaseError.toString());
}
};
//attaching the ChildEventListener to the DatabaseReference
reference1.addChildEventListener(childEventListener);
Don't forget to remove the listener in onStop()
#Override
protected void onStop() {
super.onStop();
reference1.removeEventListener(childEventListener);
}
I have solved the problem myself by using an object to store the data instead of hashmap. I am not sure why map is not working,but use of object is doing fine.
the code is given below:
sendButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String messageText = messageArea.getText().toString();
if(!messageText.equals("")){
map=new messageModel(messageText,userId);
reference1.child(""+n).setValue(map).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful())
{
reference2.child(""+n2).setValue(map).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if(task.isSuccessful())
{
messageArea.setText("");
}
}
});
}
else
{
Toast.makeText(getApplicationContext(),"server problem try again",Toast.LENGTH_SHORT).show();
}
}
});
}
}
});
try
{
reference1.addChildEventListener(new com.google.firebase.database.ChildEventListener() {
#Override
public void onChildAdded(com.google.firebase.database.DataSnapshot dataSnapshot, String s) {
map = dataSnapshot.getValue(messageModel.class);
String message = map.myMessage;
String userName = map.user;
if(userName.equals(userId)){
addMessageBox("You:\n" + message, 1);
}
else{
addMessageBox("USER:\n" + message, 2);
}
}
#Override
public void onChildChanged(com.google.firebase.database.DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(com.google.firebase.database.DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(com.google.firebase.database.DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
catch (Exception e)
{
Toast.makeText(getApplicationContext(),"error:"+e,Toast.LENGTH_SHORT).show();
}
as u can see no part of the code has been changed except the map portion.The code of messageModel class is as following:
public class messageModel {
public String myMessage;
public String user;
public messageModel()
{
}
public messageModel(String a,String b)
{
myMessage=a;
user=b;
}
}

How to retrieve certain database child and display inside the ListView

How to retrieve/call userInfo from the following database, It is an authenticated user information
StudentInformation java class.
public class StudentInformation {
String name;
String ID;
String studentID;
String email;
String phone_num;
public StudentInformation() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getID() {
return ID;
}
public void setID(String ID) {
this.ID = ID;
}
public String getStudentID() {
return studentID;
}
public void setStudentID(String studentID) {
this.studentID = studentID;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone_num() {
return phone_num;
}
public void setPhone_num(String phone_num) {
this.phone_num = phone_num;
}
}
I've tried a lot of method, but the ListView still display none and the app suddenly stopped.
public class StudentInfoActivity extends AppCompatActivity {
//add Firebase Database stuff
private FirebaseDatabase mFirebaseDatabase;
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private DatabaseReference myRef;
private String userID;
ListView mListView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_student_info);
mListView = (ListView) findViewById(R.id.listview);
//declare the database reference object. This is what we use to access the database.
//NOTE: Unless you are signed in, this will not be useable.
mAuth = FirebaseAuth.getInstance();
mFirebaseDatabase = FirebaseDatabase.getInstance();
myRef = mFirebaseDatabase.getReference();
FirebaseUser user = mAuth.getCurrentUser();
userID = user.getUid();
mAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
// User is signed in
toastMessage("User Information");
} else {}
// ...
}
}; //end authlistener
myRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// This method is called once with the initial value and again
// whenever data at this location is updated.
showData(dataSnapshot);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
} // end oncreate
private void showData(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()){
StudentInformation sInfo = new StudentInformation();
sInfo.setName(ds.child(userID).child("userInfo").getValue(StudentInformation.class).getName());
sInfo.setID(ds.child(userID).child("userInfo").getValue(StudentInformation.class).getID());
sInfo.setStudentID(ds.child(userID).child("userInfo").getValue(StudentInformation.class).getStudentID());
sInfo.setEmail(ds.child(userID).child("userInfo").getValue(StudentInformation.class).getEmail());
sInfo.setPhone_num(ds.child(userID).child("userInfo").getValue(StudentInformation.class).getPhone_num());
ArrayList<String> array = new ArrayList<>();
array.add(sInfo.getName());
array.add(sInfo.getID());
array.add(sInfo.getStudentID());
array.add(sInfo.getEmail());
array.add(sInfo.getPhone_num());
ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,array);
mListView.setAdapter(adapter);
}
} //end showdata
#Override
public void onStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthListener);
}
#Override
public void onStop() {
super.onStop();
if (mAuthListener != null) {
mAuth.removeAuthStateListener(mAuthListener);
}
}
private void toastMessage(String message){
Toast.makeText(this,message,Toast.LENGTH_SHORT).show();
}
} // end class
This is the code Im using. I've been wondering about the getchildren method, did I do something wrong in the code ?. Can anyone help me with this ?
You can go with FirebaseListAdapter .Here you won't have to manage any changes or attach listener and everything in the list gets updated when there is any change in server
To get the data please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference userInfoRef = rootRef.child("users").child(userID).child("userInfo");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String ID = ds.child("ID").getValue(String.class);
String email = ds.child("email").getValue(String.class);
String name = ds.child("name").getValue(String.class);
String phone_num = ds.child("phone_num").getValue(String.class);
String studentID = ds.child("studentID").getValue(String.class);
Log.d("TAG", ID + " / " + email + " / " + name + " / " + phone_num + " / " + studentID);
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
userInfoRef.addListenerForSingleValueEvent(eventListener);

Categories