Related
I am using firebase in android to save the user information and retrieving it.
I am getting the value from firebase database but its not casting to my POJO class
UserInformation.java
public class UserInformation {
private String phoneNo;
private String address;
public UserInformation() {
}
public UserInformation(String address, String phoneNo) {
this.phoneNo = phoneNo;
this.address = address;
}
public String getPhoneNo() {
return phoneNo;
}
public String getAddress() {
return address;
}
}
ValueEventListener
public ValueEventListener displayUserData() {
return new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
UserInformation userInformation =
dataSnapshot.getValue(UserInformation.class);
mEtAddress.setText(userInformation.getAddress());
mEtPhoneNo.setText(userInformation.getPhoneNo());
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
}
The data snapshot is not casting to UserInformation.class. I am getting all null values in it.
You seem to be attaching your listener one level above the UserInformation node in the JSON tree. In that case the result contains a snapshot with a list of snapshots. Even if there is only one snapshot, your code needs to handle the fact that it's a list.
public ValueEventListener displayUserData() {
return new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot userSnapshot: dataSnapshot.getChildren()) {
UserInformation userInformation =
userSnapshot.getValue(UserInformation.class);
mEtAddress.setText(userInformation.getAddress());
mEtPhoneNo.setText(userInformation.getPhoneNo());
}
}
My app allows you to add a Player to a node, once they have been added I am using the below method to search by phoneNum to see if that player exists in the 'users' node.
Where I am having trouble is that I need to be able to access the values from the datasnapshot for the user within the found matching node. e.g.return the value of the user id. When I attempt this it keeps showing as a null value and when I try to log to the console it complains that it is a null value which doesn't make sense as the if statement should take care of this.
The method is able to find if a player exists in the the users node and displays a Toast message to indicate this.
Code:
public void checkPlayerNum(final String phoneNum) {
DatabaseReference mDatabaseReference =
FirebaseDatabase.getInstance().getReference().child("users");
if (!TextUtils.isEmpty(phoneNum)) {
final Query phoneNumReference = mDatabaseReference.orderByChild("phoneNum").equalTo(phoneNum);
ValueEventListener phoneNumValueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.getValue() != null) {
// String key = String.valueOf(dataSnapshot.getValue());
User mUser = dataSnapshot.getValue(User.class);
String uId = mUser.getUid();
// Log.d("TAG",uId);
Toast.makeText(getApplicationContext(), "* found **"+ uId , Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), "****NOT FOUND****", Toast.LENGTH_LONG).show();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
phoneNumReference.addListenerForSingleValueEvent(phoneNumValueEventListener);
} else {
Log.e("Error","phoneNum is null");
}
}
final Query query = mFirebaseDatabase.orderByChild("phoneNum").equalTo("userPhoneNumber");
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
//here means the value exist
//do whatever you want to do
} else {
//here means the value not exist
//do whatever you want to do
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
Use this to check whether the data exist or not.
you need to do this at two steps , first check if the user exists. then you get user info by your userId.
DatabaseReference mDatabaseReference;
public void checkPlayerNum(final String phoneNum,final String userId) {
mDatabaseReference =
FirebaseDatabase.getInstance().getReference().child("users");
if (!TextUtils.isEmpty(phoneNum)) {
final Query phoneNumReference = mDatabaseReference.orderByChild("phoneNum").equalTo(phoneNum);
ValueEventListener phoneNumValueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if (dataSnapshot.getValue() != null) {
// user exists
getUserInf(userId);
} else {
Toast.makeText(getApplicationContext(), "****NOT FOUND****", Toast.LENGTH_LONG).show();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
phoneNumReference.addListenerForSingleValueEvent(phoneNumValueEventListener);
} else {
Log.e("Error","phoneNum is null");
}
}
get user info by userId. mDatabaseReference is the same as before . define it as member field .
void getUserInf(String userId) {
userValueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// get user data
User mUser = dataSnapshot.getValue(User.class);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
mDatabaseReference.child(userId).addListenerForSingleValueEvent(userValueEventListener);
}
your user Pojo should be like below.
public class User {
String email,name,phoneNum,uid;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhoneNum() {
return phoneNum;
}
public void setPhoneNum(String phoneNum) {
this.phoneNum = phoneNum;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
}
Thanks everybody I managed to achieve it by using childEventListener
public void checkingNumber(final String phoneNum){
DatabaseReference mDatabaseReference =
FirebaseDatabase.getInstance().getReference().child("users");
final Query query = mDatabaseReference;
query.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
if (dataSnapshot.getValue() != null) {
// String key = String.valueOf(dataSnapshot.getValue());
User mUser = dataSnapshot.getValue(User.class);
// String uId = mUser.getUid();
// usersDatabase.child(mUser.getUid());
// Log.d("TAG",uId);
if(mUser.getPhoneNum().equals(phoneNum)) {
String uId= mUser.getUid();
String email = mUser.getEmail();
String name = mUser.getName();
Toast.makeText(getApplicationContext(), "* found **" + " " + uId + " " + " " + email + " " + name, Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(getApplicationContext(), "****NOT FOUND****", Toast.LENGTH_LONG).show();
}
}
#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) {
}
});
}
I have registered and saved users through my app and now I want to fetch the list of usernames as shown below from Firebase database. How do I do it in list view? my database is shown below:
ArrayList<MODELCLASSNAME> Users=new ArrayList<>();
DatabaseReference df=FirebaseDatabase.getInstance().getReference().child("users");
df.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapShot user : dataSnapshot.getchildren()){
Users.add(dataSnapshot.getValue(MODELCLASSNAME.class));
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
//Now loop through your arraylist
get your database reference
firebaseDatabase = FirebaseDatabase.getInstance();
mPostDb = firebaseDatabase.getReference("User");
Now query your table
Query query = mPostDb.orderByKey();
query.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapShot user : dataSnapshot){
// Do what ever you whatever you want with this user object
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Try this method:
public void retrieveNames() {
Query myQuery = mDatabase.orderByChild("name").equalTo("INSERT-HERE-A-NAME-FOR-YOUR-SEARCH");
myQuery.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Iterator iterator = dataSnapshot.getChildren().iterator();
//FOR YOUR DATA STRUCTURE -
while (iterator.hasNext()) {
String image_uri = (String) ((DataSnapshot) iterator.next()).getValue();
String name = (String) ((DataSnapshot) iterator.next()).getValue();
String username = (String) ((DataSnapshot) iterator.next()).getValue();
YourUserObject User = new YourUserObject (image_uri, name, username);
YourArrayList.add(User);
}
YourAdapter.notifyDataSetChanged();
}
#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) {
}
});
}
I want to convert all Firebase DataSnapshot children to a list in android.
Something like this:
mFirebaseRef = new Firebase(FIREBASE_URL);
mFirebaseRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<String> td = (ArrayList<String>) dataSnapshot.getValue();
//notifyDataSetChanged();
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
I hope below code works
Firebase ref = new Firebase(FIREBASE_URL);
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
Log.e("Count " ,""+snapshot.getChildrenCount());
for (DataSnapshot postSnapshot: snapshot.getChildren()) {
<YourClass> post = postSnapshot.getValue(<YourClass>.class);
Log.e("Get Data", post.<YourMethod>());
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
Log.e("The read failed: " ,firebaseError.getMessage());
}
});
Firebase stores a sequence of values in this format:
"-K-Y_Rhyxy9kfzIWw7Jq": "Value 1"
"-K-Y_RqDV_zbNLPJYnOA": "Value 2"
"-K-Y_SBoKvx6gAabUPDK": "Value 3"
If that is how you have them, you are getting the wrong type. The above structure is represented as a Map, not as a List:
mFirebaseRef = new Firebase(FIREBASE_URL);
mFirebaseRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Map<String, Object> td = (HashMap<String,Object>) dataSnapshot.getValue();
List<Object> values = td.values();
//notifyDataSetChanged();
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
FirebaseDatabase mFirebaseDatabase = FirebaseDatabase.getInstance();
DatabaseReference databaseReference = mFirebaseDatabase.getReference(FIREBASE_URL);
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childDataSnapshot : dataSnapshot.getChildren()) {
Log.v(TAG,""+ childDataSnapshot.getKey()); //displays the key for the node
Log.v(TAG,""+ childDataSnapshot.child(--ENTER THE KEY NAME eg. firstname or email etc.--).getValue()); //gives the value for given keyname
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Hope it helps!
as Frank said Firebase stores sequence of values in the format of "key": "Value"
which is a Map structure
to get List from this sequence you have to
initialize GenericTypeIndicator with HashMap of String and your Object.
get value of DataSnapShot as GenericTypeIndicator into Map.
initialize ArrayList with HashMap values.
GenericTypeIndicator<HashMap<String, Object>> objectsGTypeInd = new GenericTypeIndicator<HashMap<String, Object>>() {};
Map<String, Object> objectHashMap = dataSnapShot.getValue(objectsGTypeInd);
ArrayList<Object> objectArrayList = new ArrayList<Object>(objectHashMap.values());
Works fine for me, Hope it helps.
I did something like this :
Firebase ref = new Firebase(FIREBASE_URL);
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
Map<String, Object> objectMap = (HashMap<String, Object>)
dataSnapshot.getValue();
List<Match> = new ArrayList<Match>();
for (Object obj : objectMap.values()) {
if (obj instanceof Map) {
Map<String, Object> mapObj = (Map<String, Object>) obj;
Match match = new Match();
match.setSport((String) mapObj.get(Constants.SPORT));
match.setPlayingWith((String) mapObj.get(Constants.PLAYER));
list.add(match);
}
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
In my case only given solution worked fine.
Screenshot of Firebase ArrayList structure:
How to fetch whole list from Firebase from DataSnapshot.
GenericTypeIndicator<Map<String, List<Education>>> genericTypeIndicator = new GenericTypeIndicator<Map<String, List<Education>>>() {};
Map<String, List<Education>> hashMap = dataSnapshot.getValue(genericTypeIndicator);
for (Map.Entry<String,List<Education>> entry : hashMap.entrySet()) {
List<Education> educations = entry.getValue();
for (Education education: educations){
Log.i(TAG, education.Degree);
}
}
Education.java: (Model class).
public class Education implements Serializable{
public String Degree;
public String Result;
}
Hope this would works fine.
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
User user = postSnapshot.getValue(User.class);
list.add(user);
}
for (int i=0;i<list.size();i++)
{
Log.e("Name",list.get(i).getname());
Log.e("Phone",list.get(i).getphone());
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
Log.e("error",firebaseError.getMessage());
}
});
Class model
class User{
String name;
String phone;
public String getname() {
return name;
}
public void setname(String name) {
this.name = name;
}
public String getphone() {
return phone;
}
public void setphone(String phone) {
this.phone = phone;
}
}
List binding
List<User> list= new ArrayList <>();
this work for you
If you use Kotlin, the next one is a good solution:
myRef.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
val list = dataSnapshot.children.map { it.getValue(YourClass::class.java)!! }
Log.d("TAG", "Value is: $list")
}
Saving and Retriving data to - from Firebase ( deprecated ver 2.4.2 )
Firebase fb_parent = new Firebase("YOUR-FIREBASE-URL/");
Firebase fb_to_read = fb_parent.child("students/names");
Firebase fb_put_child = fb_to_read.push(); // REMEMBER THIS FOR PUSH METHOD
//INSERT DATA TO STUDENT - NAMES I Use Push Method
fb_put_child.setValue("Zacharia"); //OR fb_put_child.setValue(YOUR MODEL)
fb_put_child.setValue("Joseph"); //OR fb_put_child.setValue(YOUR MODEL)
fb_put_child.setValue("bla blaaa"); //OR fb_put_child.setValue(YOUR MODEL)
//GET DATA FROM FIREBASE INTO ARRAYLIST
fb_to_read.addValuesEventListener....{
public void onDataChange(DataSnapshot result){
List<String> lst = new ArrayList<String>(); // Result will be holded Here
for(DataSnapshot dsp : result.getChildren()){
lst.add(String.valueOf(dsp.getKey())); //add result into array list
}
//NOW YOU HAVE ARRAYLIST WHICH HOLD RESULTS
for(String data:lst){
Toast.make(context,data,Toast.LONG_LENGTH).show;
}
}
}
mDatabase.child("token").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot:dataSnapshot.getChildren())
{
String key= snapshot.getKey();
String value=snapshot.getValue().toString();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(ListUser.this,databaseError.toString(),Toast.LENGTH_SHORT).show();
}
});
Only work If child have no SubChild
Works Like a Charm
final DatabaseReference senderDb = FirebaseDatabase.getInstance().getReference(Constant.NODE_MESSAGE).child(myId + "_" + otherId);
senderDb.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Map<String, Object> td = (HashMap<String,Object>) dataSnapshot.getValue();
for (DataSnapshot childDataSnapshot : dataSnapshot.getChildren()) {
DatabaseReference objRef = senderDb.child( childDataSnapshot.getKey());
Map<String,Object> taskMap = new HashMap<String,Object>();
taskMap.put("is_read", "1");
objRef.updateChildren(taskMap); //should I use setValue()...?
Log.v("Testing",""+ childDataSnapshot.getKey()); //displays the key for the node
}
//notifyDataSetChanged();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
You Need to write a custom Deserializer and then loop it and get the values of the hasmap.
Custom Deserializer:-
public class UserDetailsDeserializer implements JsonDeserializer<AllUserDetailsKeyModel> {
/*
bebebejunskjd:{
"email": "akhilbv1#gmail.com",
"mobileNum": "12345678",
"password": "1234567",
"username": "akhil"}*/
#Override public AllUserDetailsKeyModel deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
final JsonObject jsonObject = json.getAsJsonObject();
Gson gson = new Gson();
Type AllUserDetailsResponseModel =
new TypeToken<HashMap<String, AllUserDetailsResponseModel>>(){}.getType();
HashMap<String, AllUserDetailsResponseModel> user =
gson.fromJson(jsonObject, AllUserDetailsResponseModel);
AllUserDetailsKeyModel result = new AllUserDetailsKeyModel();
result.setResult(user);
return result;
}
}
The code in comments is my object model and u should replaceAllUserDetailsKeyModel with your model class and add this to the rest client like below:-
private Converter.Factory createGsonConverter() {
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(AllUserDetailsKeyModel.class, new UserDetailsDeserializer());
Gson gson = gsonBuilder.create();
return GsonConverterFactory.create(gson);
}
This the custom Convertor for Retrofit.
In your onResponse you just loop with hasmaps and get value by key and my model class looks like below:-
public class AllUserDetailsKeyModel {
private Map<String, AllUserDetailsResponseModel> result;
public Map<String, AllUserDetailsResponseModel> getResult() {
return result;
}
public void setResult(Map<String, AllUserDetailsResponseModel> result) {
this.result = result;
}
}
probably you need to give a Type T where T is your data Type and my model consists only of a hashmap and getters and setters for that.
And finally set Custom Convertor to retrofit like below:- .addConverterFactory(createGsonConverter())
Let me know if you need more clarifications.
Use GenericTypeIndicator to get List of Child Node from Firebase ArrayList structured DataBase
//Start of Code
Firebase ref = new Firebase(FIREBASE_URL);
ref.addValueEventListener(new ValueEventListener(){
#Override
public void onDataChange(DataSnapshot snapshot){
GenericTypeIndicator<List<YourClassName>> t = new GenericTypeIndicator<List<YourClassName>>{};
List<YourClassName> messages = snapshot.getValue(t);
Log.d("Get Data Size", messages.size());
}
}
#Override
public void onCancelled(FirebaseError firebaseError){
Log.e("The read failed: ",firebaseError.getMessage());
}
});
your problem is why your code doesn't work.
this your code:
Firebase ref = new Firebase(FIREBASE_URL);
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
Log.e("Count " ,""+snapshot.getChildrenCount());
for (DataSnapshot postSnapshot: snapshot.getChildren()) {
<YourClass> post = postSnapshot.getValue(<YourClass>.class);
Log.e("Get Data", post.<YourMethod>());
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
Log.e("The read failed: " ,firebaseError.getMessage());
}
})
you miss the simplest thing: getChildren()
FirebaseDatabase db = FirebaseDatabase.getInstance();
DatabaseReference reference = FirebaseAuth.getInstance().getReference("Donald Trump");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
int count = (int) dataSnapshot.getChildrenCount(); // retrieve number of childrens under Donald Trump
String[] hairColors = new String[count];
index = 0;
for (DataSnapshot datas : dataSnapshot.getChildren()){
hairColors[index] = datas.getValue(String.class);
}
index ++
for (int i = 0; i < count; i++)
Toast(MainActivity.this, "hairColors : " + hairColors[i], toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
ArrayList<String> keyList = new ArrayList<String>();
mKeyRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childDataSnapshot : dataSnapshot.getChildren()) {
String temp = childDataSnapshot.getKey();
keyList.add(temp);
i = keyList.size();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
});
This code is working fine to add all firebase key into arraylist, you can do it with firebase values, of other static values.
DatabaseReference mRootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference mMainMenuRef = mRootRef.child("tut_master");//main
DatabaseReference mSubMenuRef = mMainMenuRef.child("english");//sub
List<Tutorial> tutorialNames=new ArrayList<>();
mSubMenuRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
long id = ds.child("id").getValue(Long.class);
String name = ds.child("name").getValue(String.class);
Tutorial tut = new Tutorial();
tut.setTutId(id+"");
tut.setTutName(name);
tutList.add(tut);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
private FirebaseDatabase firebaseDatabase= FirebaseDatabase.getInstance();
private DatabaseReference databaseReference= firebaseDatabase.getReference();
private DatabaseReference mChildReference= databaseReference.child("data");
mChildReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
User commandObject = ds.getValue(User.class);
Log.d("TAG", commandObject.getMsg());
}
Toast.makeText(MainActivity.this,dataSnapshot.toString(),Toast.LENGTH_SHORT).show();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
This will help you, you just have to create a model class containing String msg.
Use Gson is my favorite solution.
mFirebaseRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Type StringListType = new TypeToken<List<String>>(){}.getType();
List<String> td = new Gson().fromJson(dataSnapshot.getValue(), StringListType);
}
});
if you think the code to get TypeToken is unintuitive. You can write a class to contain all types you need. So next time, you can get those types quickly.
class TypeTokens{
static public final Type StringListType = new TypeToken<List<String>>(){}.getType();
static public final Type StringMapType = new TypeToken<Map<String, String>>(){}.getType();
static public final Type LongMapType = new TypeToken<Map<String, Long>>(){}.getType();
static public final Type DateMapType = new TypeToken<Map<String, Date>>(){}.getType();
}
Here goes my 2 cents contribution (in Kotlin):
private fun getData(childUid:String) {
refDB = firebaseDB.reference.child(MAIN_DATABASE_FOLDER).child(childUid)
if(childEventDataListener == null) {
childEventDataListener = object : ChildEventListener {
override fun onChildAdded(snapshot: DataSnapshot, previousChildName: String?) {
for(snap in snapshot.children) {
val newParcel = snapshot.getValue(YourClassConverter::class.java)!!
}
}
override fun onChildChanged(snapshot: DataSnapshot, previousChildName: String?) { }
override fun onChildRemoved(snapshot: DataSnapshot) { }
override fun onChildMoved(snapshot: DataSnapshot, previousChildName: String?) {}
override fun onCancelled(error: DatabaseError) {}
}
refDB.addChildEventListener(childEventDataListener!!)
}
}
The class YourClassConverter shall follow this rule as noted in the getValue header's comment shown below. I prefer to use this converter since I can control the default values passed when some of them are not defined in the firebase.
This method is used to marshall the data contained in this snapshot into a class of your choosing. The class must fit 2 simple constraints:
The class must have a default constructor that takes no arguments
The class must define public getters for the properties to be assigned. Properties without a public getter will be set to their default value when an instance is deserialized
An example class might look like:
class Message {
private String author;
private String text;
private Message() {}
public Message(String author, String text) {
this.author = author;
this.text = text;
}
public String getAuthor() {
return author;
}
public String getText() {
return text;
}
}
// Later
Message m = snapshot.getValue(Message.class);
I want to convert all Firebase DataSnapshot children to a list in android.
Something like this:
mFirebaseRef = new Firebase(FIREBASE_URL);
mFirebaseRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<String> td = (ArrayList<String>) dataSnapshot.getValue();
//notifyDataSetChanged();
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
I hope below code works
Firebase ref = new Firebase(FIREBASE_URL);
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
Log.e("Count " ,""+snapshot.getChildrenCount());
for (DataSnapshot postSnapshot: snapshot.getChildren()) {
<YourClass> post = postSnapshot.getValue(<YourClass>.class);
Log.e("Get Data", post.<YourMethod>());
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
Log.e("The read failed: " ,firebaseError.getMessage());
}
});
Firebase stores a sequence of values in this format:
"-K-Y_Rhyxy9kfzIWw7Jq": "Value 1"
"-K-Y_RqDV_zbNLPJYnOA": "Value 2"
"-K-Y_SBoKvx6gAabUPDK": "Value 3"
If that is how you have them, you are getting the wrong type. The above structure is represented as a Map, not as a List:
mFirebaseRef = new Firebase(FIREBASE_URL);
mFirebaseRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Map<String, Object> td = (HashMap<String,Object>) dataSnapshot.getValue();
List<Object> values = td.values();
//notifyDataSetChanged();
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
FirebaseDatabase mFirebaseDatabase = FirebaseDatabase.getInstance();
DatabaseReference databaseReference = mFirebaseDatabase.getReference(FIREBASE_URL);
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childDataSnapshot : dataSnapshot.getChildren()) {
Log.v(TAG,""+ childDataSnapshot.getKey()); //displays the key for the node
Log.v(TAG,""+ childDataSnapshot.child(--ENTER THE KEY NAME eg. firstname or email etc.--).getValue()); //gives the value for given keyname
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Hope it helps!
as Frank said Firebase stores sequence of values in the format of "key": "Value"
which is a Map structure
to get List from this sequence you have to
initialize GenericTypeIndicator with HashMap of String and your Object.
get value of DataSnapShot as GenericTypeIndicator into Map.
initialize ArrayList with HashMap values.
GenericTypeIndicator<HashMap<String, Object>> objectsGTypeInd = new GenericTypeIndicator<HashMap<String, Object>>() {};
Map<String, Object> objectHashMap = dataSnapShot.getValue(objectsGTypeInd);
ArrayList<Object> objectArrayList = new ArrayList<Object>(objectHashMap.values());
Works fine for me, Hope it helps.
I did something like this :
Firebase ref = new Firebase(FIREBASE_URL);
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
Map<String, Object> objectMap = (HashMap<String, Object>)
dataSnapshot.getValue();
List<Match> = new ArrayList<Match>();
for (Object obj : objectMap.values()) {
if (obj instanceof Map) {
Map<String, Object> mapObj = (Map<String, Object>) obj;
Match match = new Match();
match.setSport((String) mapObj.get(Constants.SPORT));
match.setPlayingWith((String) mapObj.get(Constants.PLAYER));
list.add(match);
}
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
}
});
In my case only given solution worked fine.
Screenshot of Firebase ArrayList structure:
How to fetch whole list from Firebase from DataSnapshot.
GenericTypeIndicator<Map<String, List<Education>>> genericTypeIndicator = new GenericTypeIndicator<Map<String, List<Education>>>() {};
Map<String, List<Education>> hashMap = dataSnapshot.getValue(genericTypeIndicator);
for (Map.Entry<String,List<Education>> entry : hashMap.entrySet()) {
List<Education> educations = entry.getValue();
for (Education education: educations){
Log.i(TAG, education.Degree);
}
}
Education.java: (Model class).
public class Education implements Serializable{
public String Degree;
public String Result;
}
Hope this would works fine.
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
User user = postSnapshot.getValue(User.class);
list.add(user);
}
for (int i=0;i<list.size();i++)
{
Log.e("Name",list.get(i).getname());
Log.e("Phone",list.get(i).getphone());
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
Log.e("error",firebaseError.getMessage());
}
});
Class model
class User{
String name;
String phone;
public String getname() {
return name;
}
public void setname(String name) {
this.name = name;
}
public String getphone() {
return phone;
}
public void setphone(String phone) {
this.phone = phone;
}
}
List binding
List<User> list= new ArrayList <>();
this work for you
If you use Kotlin, the next one is a good solution:
myRef.addListenerForSingleValueEvent(object : ValueEventListener {
override fun onDataChange(dataSnapshot: DataSnapshot) {
val list = dataSnapshot.children.map { it.getValue(YourClass::class.java)!! }
Log.d("TAG", "Value is: $list")
}
Saving and Retriving data to - from Firebase ( deprecated ver 2.4.2 )
Firebase fb_parent = new Firebase("YOUR-FIREBASE-URL/");
Firebase fb_to_read = fb_parent.child("students/names");
Firebase fb_put_child = fb_to_read.push(); // REMEMBER THIS FOR PUSH METHOD
//INSERT DATA TO STUDENT - NAMES I Use Push Method
fb_put_child.setValue("Zacharia"); //OR fb_put_child.setValue(YOUR MODEL)
fb_put_child.setValue("Joseph"); //OR fb_put_child.setValue(YOUR MODEL)
fb_put_child.setValue("bla blaaa"); //OR fb_put_child.setValue(YOUR MODEL)
//GET DATA FROM FIREBASE INTO ARRAYLIST
fb_to_read.addValuesEventListener....{
public void onDataChange(DataSnapshot result){
List<String> lst = new ArrayList<String>(); // Result will be holded Here
for(DataSnapshot dsp : result.getChildren()){
lst.add(String.valueOf(dsp.getKey())); //add result into array list
}
//NOW YOU HAVE ARRAYLIST WHICH HOLD RESULTS
for(String data:lst){
Toast.make(context,data,Toast.LONG_LENGTH).show;
}
}
}
mDatabase.child("token").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot:dataSnapshot.getChildren())
{
String key= snapshot.getKey();
String value=snapshot.getValue().toString();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(ListUser.this,databaseError.toString(),Toast.LENGTH_SHORT).show();
}
});
Only work If child have no SubChild
Works Like a Charm
final DatabaseReference senderDb = FirebaseDatabase.getInstance().getReference(Constant.NODE_MESSAGE).child(myId + "_" + otherId);
senderDb.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Map<String, Object> td = (HashMap<String,Object>) dataSnapshot.getValue();
for (DataSnapshot childDataSnapshot : dataSnapshot.getChildren()) {
DatabaseReference objRef = senderDb.child( childDataSnapshot.getKey());
Map<String,Object> taskMap = new HashMap<String,Object>();
taskMap.put("is_read", "1");
objRef.updateChildren(taskMap); //should I use setValue()...?
Log.v("Testing",""+ childDataSnapshot.getKey()); //displays the key for the node
}
//notifyDataSetChanged();
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
You Need to write a custom Deserializer and then loop it and get the values of the hasmap.
Custom Deserializer:-
public class UserDetailsDeserializer implements JsonDeserializer<AllUserDetailsKeyModel> {
/*
bebebejunskjd:{
"email": "akhilbv1#gmail.com",
"mobileNum": "12345678",
"password": "1234567",
"username": "akhil"}*/
#Override public AllUserDetailsKeyModel deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
final JsonObject jsonObject = json.getAsJsonObject();
Gson gson = new Gson();
Type AllUserDetailsResponseModel =
new TypeToken<HashMap<String, AllUserDetailsResponseModel>>(){}.getType();
HashMap<String, AllUserDetailsResponseModel> user =
gson.fromJson(jsonObject, AllUserDetailsResponseModel);
AllUserDetailsKeyModel result = new AllUserDetailsKeyModel();
result.setResult(user);
return result;
}
}
The code in comments is my object model and u should replaceAllUserDetailsKeyModel with your model class and add this to the rest client like below:-
private Converter.Factory createGsonConverter() {
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(AllUserDetailsKeyModel.class, new UserDetailsDeserializer());
Gson gson = gsonBuilder.create();
return GsonConverterFactory.create(gson);
}
This the custom Convertor for Retrofit.
In your onResponse you just loop with hasmaps and get value by key and my model class looks like below:-
public class AllUserDetailsKeyModel {
private Map<String, AllUserDetailsResponseModel> result;
public Map<String, AllUserDetailsResponseModel> getResult() {
return result;
}
public void setResult(Map<String, AllUserDetailsResponseModel> result) {
this.result = result;
}
}
probably you need to give a Type T where T is your data Type and my model consists only of a hashmap and getters and setters for that.
And finally set Custom Convertor to retrofit like below:- .addConverterFactory(createGsonConverter())
Let me know if you need more clarifications.
Use GenericTypeIndicator to get List of Child Node from Firebase ArrayList structured DataBase
//Start of Code
Firebase ref = new Firebase(FIREBASE_URL);
ref.addValueEventListener(new ValueEventListener(){
#Override
public void onDataChange(DataSnapshot snapshot){
GenericTypeIndicator<List<YourClassName>> t = new GenericTypeIndicator<List<YourClassName>>{};
List<YourClassName> messages = snapshot.getValue(t);
Log.d("Get Data Size", messages.size());
}
}
#Override
public void onCancelled(FirebaseError firebaseError){
Log.e("The read failed: ",firebaseError.getMessage());
}
});
your problem is why your code doesn't work.
this your code:
Firebase ref = new Firebase(FIREBASE_URL);
ref.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot snapshot) {
Log.e("Count " ,""+snapshot.getChildrenCount());
for (DataSnapshot postSnapshot: snapshot.getChildren()) {
<YourClass> post = postSnapshot.getValue(<YourClass>.class);
Log.e("Get Data", post.<YourMethod>());
}
}
#Override
public void onCancelled(FirebaseError firebaseError) {
Log.e("The read failed: " ,firebaseError.getMessage());
}
})
you miss the simplest thing: getChildren()
FirebaseDatabase db = FirebaseDatabase.getInstance();
DatabaseReference reference = FirebaseAuth.getInstance().getReference("Donald Trump");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
int count = (int) dataSnapshot.getChildrenCount(); // retrieve number of childrens under Donald Trump
String[] hairColors = new String[count];
index = 0;
for (DataSnapshot datas : dataSnapshot.getChildren()){
hairColors[index] = datas.getValue(String.class);
}
index ++
for (int i = 0; i < count; i++)
Toast(MainActivity.this, "hairColors : " + hairColors[i], toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
ArrayList<String> keyList = new ArrayList<String>();
mKeyRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot childDataSnapshot : dataSnapshot.getChildren()) {
String temp = childDataSnapshot.getKey();
keyList.add(temp);
i = keyList.size();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
throw databaseError.toException();
}
});
This code is working fine to add all firebase key into arraylist, you can do it with firebase values, of other static values.
DatabaseReference mRootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference mMainMenuRef = mRootRef.child("tut_master");//main
DatabaseReference mSubMenuRef = mMainMenuRef.child("english");//sub
List<Tutorial> tutorialNames=new ArrayList<>();
mSubMenuRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
long id = ds.child("id").getValue(Long.class);
String name = ds.child("name").getValue(String.class);
Tutorial tut = new Tutorial();
tut.setTutId(id+"");
tut.setTutName(name);
tutList.add(tut);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
private FirebaseDatabase firebaseDatabase= FirebaseDatabase.getInstance();
private DatabaseReference databaseReference= firebaseDatabase.getReference();
private DatabaseReference mChildReference= databaseReference.child("data");
mChildReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
User commandObject = ds.getValue(User.class);
Log.d("TAG", commandObject.getMsg());
}
Toast.makeText(MainActivity.this,dataSnapshot.toString(),Toast.LENGTH_SHORT).show();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
This will help you, you just have to create a model class containing String msg.
Use Gson is my favorite solution.
mFirebaseRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Type StringListType = new TypeToken<List<String>>(){}.getType();
List<String> td = new Gson().fromJson(dataSnapshot.getValue(), StringListType);
}
});
if you think the code to get TypeToken is unintuitive. You can write a class to contain all types you need. So next time, you can get those types quickly.
class TypeTokens{
static public final Type StringListType = new TypeToken<List<String>>(){}.getType();
static public final Type StringMapType = new TypeToken<Map<String, String>>(){}.getType();
static public final Type LongMapType = new TypeToken<Map<String, Long>>(){}.getType();
static public final Type DateMapType = new TypeToken<Map<String, Date>>(){}.getType();
}
Here goes my 2 cents contribution (in Kotlin):
private fun getData(childUid:String) {
refDB = firebaseDB.reference.child(MAIN_DATABASE_FOLDER).child(childUid)
if(childEventDataListener == null) {
childEventDataListener = object : ChildEventListener {
override fun onChildAdded(snapshot: DataSnapshot, previousChildName: String?) {
for(snap in snapshot.children) {
val newParcel = snapshot.getValue(YourClassConverter::class.java)!!
}
}
override fun onChildChanged(snapshot: DataSnapshot, previousChildName: String?) { }
override fun onChildRemoved(snapshot: DataSnapshot) { }
override fun onChildMoved(snapshot: DataSnapshot, previousChildName: String?) {}
override fun onCancelled(error: DatabaseError) {}
}
refDB.addChildEventListener(childEventDataListener!!)
}
}
The class YourClassConverter shall follow this rule as noted in the getValue header's comment shown below. I prefer to use this converter since I can control the default values passed when some of them are not defined in the firebase.
This method is used to marshall the data contained in this snapshot into a class of your choosing. The class must fit 2 simple constraints:
The class must have a default constructor that takes no arguments
The class must define public getters for the properties to be assigned. Properties without a public getter will be set to their default value when an instance is deserialized
An example class might look like:
class Message {
private String author;
private String text;
private Message() {}
public Message(String author, String text) {
this.author = author;
this.text = text;
}
public String getAuthor() {
return author;
}
public String getText() {
return text;
}
}
// Later
Message m = snapshot.getValue(Message.class);