cannot convert data coming from firebase - android

i am retrieving data from child from firebase database, the first child after the reference is "cars" which i reach with mRoot
then i use iterative to reach every child in "cars"
then i get the data into car class
at first i created the class with string values then it said you can't convert long values to string
then i turned it to long and it said you cannot convert string values to long
com.google.firebase.database.DatabaseException: Failed to convert value of type java.lang.Long to String
at com.google.android.gms.internal.firebase_database.zzkt.zzb(Unknown Source)
at com.google.android.gms.internal.firebase_database.zzkt.zza(Unknown Source)
at com.google.firebase.database.DataSnapshot.getValue(Unknown Source)
at com.example.ahmed.pointoflife.LogIn$1$1.onDataChange(LogIn.java:55)
when changing
com.google.firebase.database.DatabaseException: Failed to convert a value of type java.lang.String to long
at com.google.android.gms.internal.firebase_database.zzkt.zzb(Unknown Source)
at com.google.android.gms.internal.firebase_database.zzkt.zza(Unknown Source)
at com.google.firebase.database.DataSnapshot.getValue(Unknown Source)
at com.example.ahmed.pointoflife.LogIn$1$1.onDataChange(LogIn.java:55)
mRoot.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
Car car = new Car();
car.setHospital(childSnapshot.child("hospital").getValue(Long.class));
car.setId(childSnapshot.child("id").getValue(Long.class));
car.setPassword(childSnapshot.child("password").getValue(Long.class));
h.put(car.getId().toString(),car);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
package com.example.ahmed.pointoflife;
import com.google.firebase.database.PropertyName;
public class Car {
private Long hospital,id,password;
public Car(Long hospital,Long id,Long passowrd)
{
this.hospital = hospital;
this.id = id;
this.password = passowrd;
}
Car(){
}
#PropertyName("hospital")
public Long getHospital() {
return hospital;
}
public void setHospital(Long hospital) {
this.hospital = hospital;
}
#PropertyName("id")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
#PropertyName("password")
public Long getPassword() {
return password;
}
public void setPassword(Long password) {
this.password = password;
}
}
firebase tree
https://drive.google.com/file/d/17xYkrFwZqscCdrzvfkStr6cC-VYaQHI1/view?usp=sharing
how can i take these values correctly from firebase without troubles

Assuming that the mRoot points to the Firebase root, to solve this, please change the following line of code:
mRoot.addValueEventListener(*/ ... */);
to
mRoot.child("cars").addValueEventListener(*/ ... */);
And to get the Car object you can simply use:
Car car = childSnapshot.getValue(Car.class);
Edit: Seeing your entire database structure is more clear now. So to solve this, please use the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference carsRef = rootRef.child("cars");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
Car car = ds.getValue(Car.class);
Log.d(TAG, car.getHospital());
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
carsRef.addListenerForSingleValueEvent(valueEventListener);
The output in your logcat will be: 11.
Or in a more simpler way using the Long class:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference carsRef = rootRef.child("cars");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
Long hospital = ds.child("hospital").getValue(Long.class);
Log.d(TAG, hospital);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
carsRef.addListenerForSingleValueEvent(valueEventListener);
The output will be the same.
There's also no need to use #PropertyName because all your fields in the class match the fileds in your database.

Related

Retrieve first child from a parent in Firebase

I am working on an Android application. I want the first child (first UID) of the parent 'support' and store it in a String variable. How do I get the value of the first UID from the list?
I tried one approach. It doesn't work though.
#Override
public void onDataChange(DataSnapshot dataSnapshot1) {
if (dataSnapshot1.exists()) {
String futureUID = "";
for(DataSnapshot futureUIDdatasnapshot:dataSnapshot1.getChildren() ){
futureUID = futureUIDdatasnapshot.getKey();
break;
}
/*Getting the first UID from the list of UID's in queue in 'future'*/
futureUID = dataSnapshot1.getChildren().iterator().next().getKey();
/*Moving a card from 'future' to 'serving'*/
societyServiceUIDReference.child(FIREBASE_CHILD_SERVING).child(futureUID).setValue(FIREBASE_ACCEPTED);
/*Removing the UID from 'future' after it is placed in 'serving'*/
societyServiceUIDReference.child(FIREBASE_CHILD_FUTURE).child(futureUID).removeValue();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
NOTE: 'futureUID' is the UID I want
Try the following:
DatabaseReference ref=FirebaseDatabase.getInstance().getReference().child("support");
Query queryUid=ref.orderByKey().limitToFirst(1);
queryUid.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot datas : dataSnapshot.getChildren()) {
String key=datas.getKey();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Try
DatabaseReference mDatabase;
mDatabase = FirebaseDatabase.getInstance().getReference();
.orderByKey().limitToFirst(n) is what does the trick. It orders the query results by key and returns only the first n results; in this case 1
mDatabase.getChild("support").orderByKey().limitToFirst(1)
.addListenerForSingleValueEvent(new ValueEventListener () {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
for (DataSnapshot supportItem: dataSnapshot.getChildren()) {
String futureUID =supportItem.getKey();
}
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
//Catch your error here
}
});
see Work with Lists of Data on Android

get a value with different key Firebase Realtime DB

so i want to create a refferal code system,using firebase realtime database,but i found a difficult,how i can get all the value in key refferal?
i already have the code,but its just give me the value from my uid,
Show below:-
Query query = mDatabase.child(uid).orderByChild("refferal_status");
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot movieSnapshot : dataSnapshot.getChildren()) {
UserModel movie = dataSnapshot.getValue(UserModel.class);
if (movie.getRefferal_status().equals("akmKA")) {
Toast.makeText(SpinActivity.this, movie.getRefferal_status(), Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Class Model
String email;
String point;
String checkin;
String limitation;
String refferal_status;
public UserModel(){
}
public UserModel(String email,String point,String checkin,String limitation,String refferal_status){
this.email = email;
this.point = point;
this.checkin = checkin;
this.limitation = limitation;
this.refferal_status = refferal_status;
}
//setter getter here
}
so this is my database
Image
Try this !
Note:- equals expect String object .
if ("akmKA".equals(movie.getRefferal_status())) {
Toast.makeText(SpinActivity.this, movie.getRefferal_status(), Toast.LENGTH_SHORT).show();
}
Final code
Query query = mDatabase.child(uid).orderByChild("refferal_status");
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot movieSnapshot : dataSnapshot.getChildren()) {
UserModel movie = dataSnapshot.getValue(UserModel.class);
if ("akmKA".equals(movie.getRefferal_status())) {
Toast.makeText(SpinActivity.this, movie.getRefferal_status(), Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});

Not able to retrieve value in firebase database

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());
}
}

Cannot read list from Firebase, Map expected [duplicate]

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);

How to extract a list of objects from Firebase DataSnapshot on android

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);

Categories

Resources