I am trying to populate a recycler view using nested queries. The first query goes to groups_list node and takes data in the node and the unique key. Then it goes to groups node with the key and gets data under that key. The result of both the queries needs to be updated in recycler view.
In short, the first query gets some data and a key, the key is used to make the second query. The result from both these queries need to be updated in the recycler view. I am using a model class and recycler view adapter for this.
But I am getting an error below.
My Fragment is as follows:
// Firebase
fbDatabaseRootNode = FirebaseDatabase.getInstance().getReference();
fbDatabaseRefGroupList = fbDatabaseRootNode.child("groups_list").child(current_user_id);
fbDatabaseRefGroups = fbDatabaseRootNode.child("groups");
fbDatabaseRefGroupList.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
// Array to Get Group List
lGroupsList = new ArrayList<>();
if (dataSnapshot.exists()) {
// Clear Array to Get Group List
lGroupsList.clear();
for (DataSnapshot glSnapshot : dataSnapshot.getChildren()) {
// Use The Model To Format Array List and Pass It Into It
GroupsListModel g = glSnapshot.getValue(GroupsListModel.class);
// Array to Get Group List
lGroupsList.add(g);
String groupID = String.valueOf(glSnapshot.getKey());
fbDatabaseRefGroups.child(groupID).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
for (DataSnapshot gSnapshot : dataSnapshot.getChildren()) {
// Use The Model To Format Array List and Pass It Into It
GroupsListModel g = gSnapshot.getValue(GroupsListModel.class);
// Array to Get Group List
lGroupsList.add(g);
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
aGroupList = new GroupsListAdapter(getContext(), lGroupsList);
rvGroupList.setAdapter(aGroupList);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
System.out.println("The read failed: " + databaseError.getCode());
}
});
And My Firebase Database Structure Looks Like
"groups" : {
"-LaPfENd0G4pHlejrcd6" : {
"group_creation_date" : 1553078221782,
"group_logo" : "0",
"group_member_count" : "0",
"group_name" : "dog lovers",
"group_tagline" : "we love dogs..."
},
"-LaPhG0YHnF3FG0Czxom" : {
"group_creation_date" : 1553078751686,
"group_logo" : "0",
"group_member_count" : "0",
"group_name" : "hi",
"group_tagline" : "hello"
}
},
"groups_list" : {
"F81wvGx9a7fXRrfVPQMhQtkM0wv2" : {
"-LaPfENd0G4pHlejrcd6" : {
"block_status" : "0",
"hide_status" : "0",
"notification_status" : "0",
"pin_sequence" : "0",
"report_status" : "0"
},
"-LaPhG0YHnF3FG0Czxom" : {
"block_status" : "0",
"hide_status" : "0",
"notification_status" : "0",
"pin_sequence" : "0",
"report_status" : "0"
}
}
},
The Model Class Is
public class GroupsListModel {
private String block_status;
private String hide_status;
private String notification_status;
private String pin_sequence;
private String report_status;
private String group_name;
private Long group_creation_date;
private String group_logo;
private String group_member_count;
private String group_tagline;
public GroupsListModel() {
}
public GroupsListModel(String block_status, String hide_status, String notification_status, String pin_sequence, String report_status, String group_name, Long group_creation_date, String group_logo, String group_member_count, String group_tagline) {
this.block_status = block_status;
this.hide_status = hide_status;
this.notification_status = notification_status;
this.pin_sequence = pin_sequence;
this.report_status = report_status;
this.group_name = group_name;
this.group_creation_date = group_creation_date;
this.group_logo = group_logo;
this.group_member_count = group_member_count;
this.group_tagline = group_tagline;
}
public String getBlock_status() {
return block_status;
}
public void setBlock_status(String block_status) {
this.block_status = block_status;
}
public String getHide_status() {
return hide_status;
}
public void setHide_status(String hide_status) {
this.hide_status = hide_status;
}
public String getNotification_status() {
return notification_status;
}
public void setNotification_status(String notification_status) {
this.notification_status = notification_status;
}
public String getPin_sequence() {
return pin_sequence;
}
public void setPin_sequence(String pin_sequence) {
this.pin_sequence = pin_sequence;
}
public String getReport_status() {
return report_status;
}
public void setReport_status(String report_status) {
this.report_status = report_status;
}
public String getGroup_name() {
return group_name;
}
public void setGroup_name(String group_name) {
this.group_name = group_name;
}
public Long getGroup_creation_date() {
return group_creation_date;
}
public void setGroup_creation_date(Long group_creation_date) {
this.group_creation_date = group_creation_date;
}
public String getGroup_logo() {
return group_logo;
}
public void setGroup_logo(String group_logo) {
this.group_logo = group_logo;
}
public String getGroup_member_count() {
return group_member_count;
}
public void setGroup_member_count(String group_member_count) {
this.group_member_count = group_member_count;
}
public String getGroup_tagline() {
return group_tagline;
}
public void setGroup_tagline(String group_tagline) {
this.group_tagline = group_tagline;
}
}
And The Error is
Can't convert object of type java.lang.Long to type com.example.myproject
The logs from datasnapshots are coming as follows... first one...
The log from second one...
Possible Solution 1 (Passing To Recycler View An Issue Otherwise Working)
This seems to be getting the data in proper sequence now just have to pass it into the Model Array List and Set The Adapter
// Get The Data
fbDatabaseRefGroupList.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
if (dataSnapshot.exists()) {
final String groupID = dataSnapshot.getKey();
final String blockStatus = (String) dataSnapshot.child("block_status").getValue();
final String hideStatus = (String) dataSnapshot.child("hide_status").getValue();
final String notificationStatus = (String) dataSnapshot.child("notification_status").getValue();
final String pinSequence = (String) dataSnapshot.child("pin_sequence").getValue();
final String reportStatus = (String) dataSnapshot.child("report_status").getValue();
fbDatabaseRefGroups.child(groupID).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String groupName = (String) dataSnapshot.child("group_name").getValue();
String groupTagLine = (String) dataSnapshot.child("group_name").getValue();
String groupMemberCount = (String) dataSnapshot.child("group_name").getValue();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
Possible Solution 2 (List Merging Is An Issue - Otherwise Working)
// Firebase
fbDatabaseRootNode = FirebaseDatabase.getInstance().getReference();
fbDatabaseRefGroupList = fbDatabaseRootNode.child("groups_list").child(current_user_id);
fbDatabaseRefGroups = fbDatabaseRootNode.child("groups");
// Array to Get Group List
lGroupsListList = new ArrayList<>();
lGroupsList = new ArrayList<>();
lCombinedList = new ArrayList<>();
// Clear Array to Get Group List
lGroupsList.clear();
// Clear Array to Get Group List
lGroupsListList.clear();
// Clear Array to Get Group List
lCombinedList.clear();
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
// Use The Model To Format Array List and Pass It Into It
GroupsListModel g = ds.getValue(GroupsListModel.class);
// Array to Get Group List
lGroupsListList.add(g);
final String key = ds.getKey();
final String blockStatus = (String) ds.child("block_status").getValue();
DatabaseReference keyRef = fbDatabaseRootNode.child("groups").child(key);
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// Use The Model To Format Array List and Pass It Into It
GroupsListModel g = dataSnapshot.getValue(GroupsListModel.class);
// Array to Get Group List
lGroupsList.add(g);
String groupName = (String) dataSnapshot.child("group_name").getValue();
Log.d(TAG, "groupdetails: " + key + "--" + groupName + "--" + blockStatus);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
keyRef.addListenerForSingleValueEvent(eventListener);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage()); //Don't ignore errors!
}
};
aGroupList = new GroupsListAdapter(getContext(), lGroupsList);
rvGroupList.setAdapter(aGroupList);
fbDatabaseRefGroupList.addListenerForSingleValueEvent(valueEventListener);
#Prateek Jain Your answer is giving error please see screenshot below:
Working Solution Based on Prateek Jains Inputs
public class GroupsListFragment extends Fragment {
private static final String TAG = "GroupsListFragment";
// Recycler View
private RecyclerView rvGroupList;
private GroupsListAdapter aGroupList;
private List<GroupsListModel> lGroupsListList;
private List<GroupsListModel> lGroupsList;
private List<GroupsListModel> lCombinedList;
// Firebase
private FirebaseAuth mAuth;
private DatabaseReference fbDatabaseRootNode;
private DatabaseReference fbDatabaseRefGroupList;
private DatabaseReference fbDatabaseRefGroups;
private String current_user_id;
private String groupID;
private List<String> lgroupIDs;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_groups_list, container, false);
mAuth = FirebaseAuth.getInstance();
current_user_id = mAuth.getCurrentUser().getUid();
// Init Recycler View
rvGroupList = view.findViewById(R.id.f_groups_list_groups_list);
rvGroupList.setHasFixedSize(true);
rvGroupList.setLayoutManager(new LinearLayoutManager(getActivity()));
// Firebase
fbDatabaseRootNode = FirebaseDatabase.getInstance().getReference();
fbDatabaseRefGroupList = fbDatabaseRootNode.child("groups_list").child(current_user_id);
fbDatabaseRefGroups = fbDatabaseRootNode.child("groups");
// Get The Data
fbDatabaseRefGroupList.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
// Array to Get Group List
lGroupsList = new ArrayList<>();
if (dataSnapshot.exists()) {
// Clear Array to Get Group List
lGroupsList.clear();
final String groupID = dataSnapshot.getKey();
final String blockStatus = (String) dataSnapshot.child("block_status").getValue();
final String hideStatus = (String) dataSnapshot.child("hide_status").getValue();
final String notificationStatus = (String) dataSnapshot.child("notification_status").getValue();
final String pinSequence = (String) dataSnapshot.child("pin_sequence").getValue();
final String reportStatus = (String) dataSnapshot.child("report_status").getValue();
fbDatabaseRefGroups.child(groupID).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
Long groupCreationDate = (Long) dataSnapshot.child("group_creation_date").getValue();
String groupLogo = (String) dataSnapshot.child("group_logo").getValue();
String groupMemberCount = (String) dataSnapshot.child("group_member_count").getValue();
String groupName = (String) dataSnapshot.child("group_name").getValue();
String groupTagLine = (String) dataSnapshot.child("group_tagline").getValue();
lGroupsList.add(new GroupsListModel(blockStatus, hideStatus, notificationStatus, pinSequence,
reportStatus, groupName, groupCreationDate, groupLogo, groupMemberCount, groupTagLine));
aGroupList.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
aGroupList = new GroupsListAdapter(getContext(), lGroupsList);
rvGroupList.setAdapter(aGroupList);
}
}
#Override
public void onChildChanged(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onChildRemoved(#NonNull DataSnapshot dataSnapshot) {
}
#Override
public void onChildMoved(#NonNull DataSnapshot dataSnapshot, #Nullable String s) {
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
return view;
}
}
You have to add the required data to the list which is being used by your adapter to render the views. Once that is done you must call notifyDataSetChanged, so that adapter can reload its data from the updated list.
fbDatabaseRefGroups.child(groupID).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
String groupName = (String) dataSnapshot.child("group_name").getValue();
String groupTagLine = (String) dataSnapshot.child("group_name").getValue();
String groupMemberCount = (String) dataSnapshot.child("group_name").getValue();
lGroupsList.add(new GroupsListModel(groupName, groupMemberCount, groupTagLine));
aGroupList.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
Related
I am getting this error for every child under the parent node (GID) for Games in my Firebase json tree.
So that error message is for AwayTeam, HomeTeam, AwayScore, HomeScore, etc...Its like it did NOT map anything properly!?
The firebase structure is like the following:
Games
--- GID
----- AwayTeam
----- HomeTeam
----- AwayScore
----- HomeScore
etc...
My Adapter file is like the following:
public class PoolAdapter extends RecyclerView.Adapter<PoolAdapter.PoolViewHolder> {
public PoolAdapter(Dashboard dashboardFragment, String userID) {
this.mDashboardFragment = dashboardFragment;
mPoolRef = FirebaseDatabase.getInstance().getReference();
playerInPoolRef = mPoolRef.child("PlayerInPool").child(userID).orderByValue().equalTo(true);
playerInPoolRef.addValueEventListener(new PlayersInPoolChildEventListener());
}
private class PlayersInPoolChildEventListener implements ValueEventListener {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
getPoolData(dataSnapshot);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {}
}
private void getPoolData(DataSnapshot dataSnapshot) {
for(DataSnapshot snapshot: dataSnapshot.getChildren()) {
String poolID = snapshot.getKey();
poolRef = mPoolRef.child("Pools").child(poolID);
poolRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
getGameData(dataSnapshot);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {}
});
}
}
private void getGameData(DataSnapshot dataSnapshot) {
String gameID = dataSnapshot.child("GameId").getValue().toString();
gameRef = mPoolRef.child("Games").child(gameID);
gameRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
loadPlayerDashboard(dataSnapshot);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {}
});
}
private void loadPlayerDashboard(DataSnapshot dataSnapshot) {
Log.d(TAG, "*** Database snapshot: " + dataSnapshot); <-- Displays the correct Firebase information
Pools pool = dataSnapshot.getValue(Pools.class);
mPools.add(pool);
Collections.sort(mPools);
}
}
My Model class object is as follows:
public class Pools implements Comparable<Pools> {
private String _poolID;
//
private String _poolName;
private String _poolPassword;
private String _gameID;
private String _awayTeam;
private String _homeTeam;
private String _gameTime;
private String _gameDate;
public Pools() { }
public Pools(String poolID, String poolName, String gameID, String awayTeamName, String homeTeamName, String gameDate, String gameTime) {
this._poolID = poolID;
this._poolName = poolName;
//
this._gameID = gameID;
this._awayTeam = awayTeamName;
this._homeTeam = homeTeamName;
this._gameDate = gameDate;
this._gameTime = gameTime;
}
public String get_poolID() {
return _poolID;
}
public void set_poolID(String _poolID) {
this._poolID = _poolID;
}
public String get_poolName() {
return _poolName;
}
public void set_poolName(String _poolName) {
this._poolName = _poolName;
}
public String get_poolPassword() {
return _poolPassword;
}
public void set_poolPassword(String _poolPassword) {
this._poolPassword = _poolPassword;
}
public String get_gameID() {
return _gameID;
}
public void set_gameID(String _gameID) {
this._gameID = _gameID;
}
public String get_awayTeam() {
return _awayTeam;
}
public void set_awayTeam(String _awayTeam) {
this._awayTeam = _awayTeam;
}
public String get_homeTeam() {
return _homeTeam;
}
public void set_homeTeam(String _homeTeam) {
this._homeTeam = _homeTeam;
}
public String get_gameTime() {
return _gameTime;
}
public void set_gameTime(String _gameTime) {
this._gameTime = _gameTime;
}
public String get_gameDate() {
return _gameDate;
}
public void set_gameDate(String _gameDate) {
this._gameDate = _gameDate;
}
}
which has all the getters and setters so I am not sure why I am getting the error!?
I know the data is there as log log statement that you see above in my Adapter displays the following:
*** Database snapshot: DataSnapshot { key = 2019020300, value = {HomeTeam=Los Angeles Rams, GSIS=57833, GameYear=2019, isPlayed=true, hBackground=hTeam/rams.png, HomeId=29, hScore=0, GameTime=6:30, AwayId=31, aBackground=aTeam/patriots.png, SportID=1, aScore=0, Qtr=Pregame, WeekId=22, GameDate=20190203, AwayTeam=New England Patriots, SeasonType=SB} }
Does anyone know how I can resolve this!?
You need to iterate over dataSnapshot.getChildren(
for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
Pools pool = childSnapshot.getValue(Pools.class);
}
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 have a function which write data into database
private void startCommenting() {
final String comment_val = meditComment.getText().toString().trim();
meditComment.setText("");
if (!TextUtils.isEmpty(comment_val)) {
mProgress.show();
final DatabaseReference newPost = mComment.child(post_key).push();
final String commentkey = newPost.getKey();
mUser.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Map<String,Object> checkoutData=new HashMap<>();
checkoutData.put("time",ServerValue.TIMESTAMP);
newPost.setValue(checkoutData);
newPost.child("comment").setValue(comment_val);
newPost.child("uid").setValue(dataSnapshot.child("id").getValue());
newPost.child("blogpost").setValue(dataSnapshot.child("blogkey").getValue());
newPost.child("userimage").setValue(dataSnapshot.child("image").getValue());
newPost.child("username").setValue(dataSnapshot.child("name").getValue());
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
After this function was called, a Query was made to get the data which contains the right post_key in the child ("blogpost").
mpostComment.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startCommenting();
mQueryCurrentComment = mComment.child(post_key).orderByChild("blogpost").equalTo(post_key);
mQueryCurrentComment.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String currentuserid;
String lastuserid = "";
String currentcommentuid;
for (DataSnapshot dsp : dataSnapshot.getChildren()) {
currentuserid = dsp.child("uid").getValue().toString();
Log.d(TAG, "user newid: " + currentuserid);
Log.d(TAG, "user oldid: " + lastuserid);
if (currentuserid.equals(lastuserid)) {
} else {
final DatabaseReference newCommentLike = mComment.child(currentuserid).push();
Map<String, Object> checkTime = new HashMap<>();
checkTime.put("time", ServerValue.TIMESTAMP);
newCommentLike.setValue(checkTime);
newCommentLike.child("location").setValue(location_key);
newCommentLike.child("category").setValue(category_key);
newCommentLike.child("pressed").setValue("false");
newCommentLike.child("message").setValue(" has also commented your post. ");
newCommentLike.child("blogpost").setValue(post_key);
newCommentLike.child(post_key).setValue(true);
}
lastuserid = currentuserid;
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
});
However, the Query was triggered twice, one before the new item was added, another after new item was added, which looks like below:
How can I only perform the actions inside Query after the newest item was added and not twice? Any help is appreciated!
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);