I have been struggling with this issue for about three days. Or may be I am not understanding the who concept of addValueEventListener(). I have a POJO class.
public class InstantMessage {
private String UID;
private String email;
private String password;
private String type;
public InstantMessage() {
}
public InstantMessage(String newUID, String newEmail, String newPassword, String newType) {
UID = newUID;
email = newEmail;
password = newPassword;
type = newType;
}
public void setUID(String newUID) {
UID = UID;
}
public void setEmail(String newEmail) {
email = newEmail;
}
public void setPassword(String newPassword) {
password = newPassword;
}
public void setType(String newType) {
type = newType;
}
public String getUID() {
return UID;
}
public String getEmail()
{
return email;
}
public String getPassword()
{
return password;
}
public String getType()
{
return type;
}
}
What I am actually trying to achieve is to fetch "type" node from Firebase database. My database reference is:
mDatabaseReference = FirebaseDatabase.getInstance().getReference().child("Users");
I have tried to loop through the Datasnapshot object still no luck.
Here's what I am trying to do.
private void showData(){
mDatabaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
InstantMessage iM1 = dataSnapshot.getValue(InstantMessage.class);
//System.out.println("The type is:" + iM1.getType());
sampleUser.add(iM1);
studentAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
As you can see in the logs that Datasnapshot is getting an object I am looking for but values are null.
I am so sorry if it's just a novice question but I am trying hard to learn it. Any help would be greatly appreciated.
You're getting a list of all users (from /Users), and then try to map the entire result to a single InstantMessage. That won't work, since the properties in InstantMessage don't exist straight in /Users, they are one level deeper in your JSON.
To solve this problem, you'll need to loop over the child nodes of your snapshot to get at the individual messages:
mDatabaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot messageSnapshot: dataSnapshot.getChildren()) {
InstantMessage iM1 = messageSnapshot.getValue(InstantMessage.class);
sampleUser.add(iM1);
}
studentAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore errors
}
});
Related
Situation: I'm trying to retrieve a string from the key "title" under the first push key (most recent object) inside my Realtime Database, but I keep getting "null".
MainActivity.java
...
mDatabaseReference.limitToFirst(1).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
ExecutiveOrder executiveOrder = snapshot.getValue(ExecutiveOrder.class);
Log.i("MainActivity", "Title: " + executiveOrder.getTitle());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.e("Executive Order", "The read failed: " + databaseError.getDetails());
}
});
...
ExecutiveOrder.java
package com.example.cleeg.part;
import com.google.firebase.database.IgnoreExtraProperties;
#IgnoreExtraProperties
public class ExecutiveOrder {
private String mTitle;
private String mDate;
private String mSummary;
private String mText;
// Default constructor
public ExecutiveOrder() {}
public ExecutiveOrder(String title, String date, String text) {
mTitle = title;
mDate = date;
mText = text;
}
public String getTitle() { return mTitle; }
public String getDate() { return mDate; }
public String getSummary() { return mSummary; }
public String getText() { return mText; }
}
UPDATE: The problem was that I didn't have setters in my ExecutiveOrder.java
There are couple of changes to be done. It worked fine to me on very similar DB structure:
mDatabaseReference definition should not include "Executive Branch", because the branch is actually the value to be returned as object
of executiveOrder
I would recommend to change ValueEventListener to ChildEventListener, and update #Override methods accordingly (the names of the methods are slightly different).
I updated you code with needed changes - it should work. Please try. Well... as I can't test it on exact same DB, it may include couple of typos. Apologize if so. But it worked on very similar DB.
mDatabaseReference = mFirebaseDatabase.getReference();
ChildEventListener recentListener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
if (dataSnapshot.getChildrenCount() > 0) {
for (DataSnapshot ds1 : dataSnapshot.getChildren()) {
ExecutiveOrder executiveOrder = ds1.getValue(ExecutiveOrder.class);
String title = executiveOrder.getTitle();
Log.i("MainActivity", "Title: " + title);
}
}
}
#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) {
}
}
};
mDatabaseReference.addChildEventListener(recentListener);
There is a mismatch between variable names of the class and the corresponding database entries. The key in the database has the name "title" whereas you declare it as "mTitle" in your ExecutiveOrder.java class. Therefore, you are getting 'null'. Change the variable names in your ExecutiveOrder.java to match the "key" names exactly in the database and it should work fine.
All the best!!
I am implementing Firebase and DataSnapshot return null to custom java object. I have try to solved this issue by following some answer using this site also but I don't know where is exact issue in my code.
Here I am attaching my screenshot of firebase database so kindly help me resolve this issue
Below is my model.
public class ChatModel {
private String messege;
private String user;
private int intType;
public ChatModel(){}
public ChatModel(String messege, String user, int intType) {
this.messege = messege;
this.user = user;
this.intType = intType;
}
public String getMessege() {
return messege;
}
public void setMessege(String messege) {
this.messege = messege;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public int getIntType() {
return intType;
}
public void setIntType(int intType) {
this.intType = intType;
}
}
and here is my activitycode.
DatabaseReference messagesReference = reference1.child("messages/"+ UserDetails.username + "_" + UserDetails.chatWith);
Log.e("messages URL "," ==>"+messagesReference);
messagesReference .addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Log.e("messages Referencev "," ==>"+dataSnapshot.toString());
ChatModel map = dataSnapshot.getValue(ChatModel.class);
String message = map.getMessege();
String userName = map.getUser();
Log.e("message "," ==>"+message); // Here I am getting null value
}
#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) {
}
});
and logcat show message like this.
==>DataSnapshot { key = -KslrqBPRMNKkWQO15h_, value = {message=Hi This is sakib, user=sakib} }
Your keys are mismatch that's why it's returning null value check your screenshot and your ChatModel class, remove str from your ChatModel class variables, and generate getter setter again
This might help you.
public class ChatModel {
private String messege;
private String user;
private int intType;
// TODO generate getter setter again
}
either you can get values via map as well
Map<String,String> map=(Map<String,String>)dataSnapshot.getValue();
String message = map.get("message");
String userName = map.get("user");
Log.e("message "," ==>"+message);
Try to rename your model
private String message;
public String getMessage(){ return message;}
i had the same issue and it worked after i named the properties exactly like they are named in the firebase Database.
You can try to use dataSnapshot.getChildren() in the for loop, like this:
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
if (dataSnapshot.exists()) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
ChatModel map = snapshot.getValue(ChatModel.class);
String message = map.getMessege();
String userName = map.getUser();
}
}
Here is how I intend my code to work. I first make sure that a unique placeID VALUE exists in my database (as seen in the picture), and set it to the query object. If the dataSnapshot of that VALUE exists, I want to retrieve the corresponding businessID using
businessID = resInfo_P.getBusinessID();
However it returns a null object reference.
Question: How do I retrieve the businessID VALUE without returning a null?
Code:
ref2 = FirebaseDatabase.getInstance().getReference();
mDatabase = FirebaseDatabase.getInstance().getReference();
Query query = ref2.child("place_id").orderByChild("placeID").equalTo(resID);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
RestaurantInformation resInfo_P = dataSnapshot
.child("place_id")
.child(resID).getValue(RestaurantInformation.class);
businessID = resInfo_P.getBusinessID(); // null object exception
} else {
...
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Model
public class RestaurantInformation {
private String resName;
private String status;
private String businessID;
private String placeID;
public RestaurantInformation() {
}
public RestaurantInformation(String businessID, String placeID) {
this.businessID = businessID;
this.placeID = placeID;
}
public RestaurantInformation(String resName) {
this.resName = resName;
}
public String getResName() {
return resName;
}
public void setResName(String resName) {
this.resName = resName;
}
public String getBusinessID() {
return businessID;
}
public void setBusinessID(String placeID) {
this.businessID = placeID;
}
public String getPlaceID() {
return placeID;
}
public void setPlaceID(String placeID) {
this.placeID = placeID;
}
}
When you execute a query against the Firebase Database, there will potentially be multiple results. So the snapshot contains a list of those results. Even if there is only a single result, the snapshot will contain a list of one result.
You will need to handle this list in your code by iterating over the children of the snapshot:
Query query = ref2.child("place_id").orderByChild("placeID").equalTo(resID);
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
RestaurantInformation resInfo_P = childSnapshot.getValue(RestaurantInformation.class);
businessID = resInfo_P.getBusinessID();
}
} else {
...
}
I get each profile back as objects and put them into an array list. The first println shows size as 1 then the second one shows the size as 0. How is this possible?... My Profile class has getters for each attribute and an empty Profile constructor.
// Initialize Profiles Array, global variable in my project
ArrayList<Profile> profileObjects = new ArrayList<>();
// GET FIREBASE PROFILE DATA, PUT INTO ARRAY
ref.child("Users").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot child : dataSnapshot.getChildren()){
Profile profiles = child.getValue(Profile.class);
profileObjects.add(profiles);
}
System.out.println("GETTTINGGGGG BACKKKKKKKKKKKKKKKKKKKKKKK 1: " + profileObjects.size());
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
System.out.println("GETTTINGGGGG BACKKKKKKKKKKKKKKKKKKKKKKK 2: " + profileObjects.size());
Picture of my data in Firebase:
you can get all user's data then get "pic" from it or you can get only "pic" reference.
ref.child("Users").child(userId).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// to get all user object ,then you can get pic url from it by calling user.getPic() for example
Usermodel user = dataSnapshot.getValue(Usermodel .class);
String picUrl = user.getPic();
// or you can get "pic" value only
String picUrl = dataSnapshot.child("pic").getValue(String.class);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
your UserModel class could be like this
public class UserModel {
public UserModel() {
}
String name, age, gender, pic;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getPic() {
return pic;
}
public void setPic(String pic) {
this.pic = pic;
}
}
you get null caue of
String picUrl = dataSnapshot.child("Uid").child("pic").toString();
where Uid is Just String not variable
you need to use
for (DataSnapshot child : dataSnapshot.getChildren())
{
// each child is user
// if you have use model do this
Usermodel um = child.getValue(Usermodel .class);
String picurl = um.getpicurl();
}
I use firebase to store data , but I could not get the list of data
from firabse ,Specifically I want to get arraylist of person object.
here is the class person
public class Person {
private String name;
private String username;
public Person() {
}
public Person(String name, String username) {
this.name = name;
this.username = username;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
and here is data structure
You can fetch the data with any of the event listeners. Here is with child event listener.
List<Person> persons = new ArrayList<>();
ChildEventListener listener = new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Person person = dataSnapshot.getValue(Person.class);
persons.add(person);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
Person person = dataSnapshot.getValue(Person.class);
persons.remove(person);
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
FirebaseDatabase.getInstance().getReference().child("persons").addChildEventListener(listener);
Ugur B answers also correct one. Here,You can also fetch firebase data by using the ValueEventListener too...
ArrayList<String> arrayListVal = new ArrayList<String>();
fbref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
for (DataSnapshot postSnapshot : snapshot.getChildren()) {
Person person = postSnapshot.getValue(Person.class);
//Adding it to a ArrayList
arrayListVal.add(person);
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
System.out.println("Failed to fetch data: " + firebaseError.getMessage());
}
});