I want to reach second child directly , first child name is random.
I want to reach kullaniciadi child;
https://i.hizliresim.com/dO58mp.png
try this:
DatabaseReference db=FirebaseDatabase.getInstance().getReference().child("Kullanicilar");
db.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot data: dataSnapshot.getChildren()){
String kullaniciad=data.child("kullaniciadi").getValue().toString();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
Here you have the datasnapshot at child Kullanicilar. Then you iterate inside of it and get the child kullaniciadi that is under the pushids
Related
Hello all i have a my fire-base structure like this
Firebase Database
I have an array list inside an node in fire-base , I need to loop through this list and jump to each ID to get information i need like the database photo shows.
what I've tried so far
public static void checkIfCurrentUserLiked(final HomeFragment.PostsViewHolder postsViewHolder, String postKey) {
userID = Objects.requireNonNull(FirebaseAuth.getInstance().getCurrentUser()).getUid();
likesRef = FirebaseDatabase.getInstance().getReference().child("likes");
postsRef = FirebaseDatabase.getInstance().getReference().child(postKey);
postsRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.hasChild("likes")) {
for (DataSnapshot ds : dataSnapshot.child("likes").getChildren()) {
likesRef.child(Objects.requireNonNull(ds.getValue()).toString())
.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
Like like = snapshot.getValue(Like.class);
if (like != null && like.getLikedUserID().equals(userID)) {
postsViewHolder.likesImage.setImageResource
(R.drawable.ic_item_home_post_like_filled);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) { }
});
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) { }
});
}
i have no error , just nothing happens , data are not fetched as expected
Change this:
postsRef = FirebaseDatabase.getInstance().getReference().child(postKey);
into this:
postsRef = FirebaseDatabase.getInstance().getReference().child("posts").child(postKey);
According to your database, you have node posts before the postKey, therefore you need to add it when referencing to a location.
I have fragment activity called NewRescueRequest that loads values from a database child node.
databaseReference.child(firebaseAuth.getUid()).addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
RequestEntries requestEntries = dataSnapshot.getValue(RequestEntries.class);
requestfirstname.setText(requestEntries.getRequestFirstName() + " " + requestEntries.getRequestLastName());
requestcontactnumber.setText(requestEntries.getRequestContactNumber());
requestlocation.setText(requestEntries.getRequestLocation());
requestlandmarks.setText(requestEntries.getRequestLandmarks());
When the child is moved to a different node, the app crashes. I want to make it go to a different activity when the database child is removed from the node. I tried using ValueEventListener on the onCreateView method.
databaseReference.child(firebaseAuth.getUid()).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if(dataSnapshot.exists()){
}
else{
setRequestFragment();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
The if(dataSnapshot.exists()) must also be included into the first code snippet.
I'm trying to retrieve nested data from multiple records and display them in a ListView. My data is recorded like so:
I want to display the GroupNumber and the GroupVaccinationDate of all GroupVaccinations recorded in a listView but at the moment the listView remains empty when I run the following code:
listView = (ListView)findViewById(R.id.listItemAllGroupVaccinations);
databaseReference = FirebaseDatabase.getInstance().getReference("groupVaccinations");
groupVaccinations = new ArrayList<>();
protected void onStart(){
super.onStart();
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot groupVaccinationSnapshot : dataSnapshot.getChildren()){
GroupVaccination groupVaccination = groupVaccinationSnapshot.getValue(GroupVaccination.class);
groupVaccinations.add(groupVaccination);
}
AllGroupVaccinationList groupVaccinationInfoAdapter = new AllGroupVaccinationList(ActivityAllGroupVaccinations.this, groupVaccinations);
listView.setAdapter(groupVaccinationInfoAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
Any help or suggestions would be greatly appreciated!
Gaston's answer will show you all vaccinations in a single group. If instead you want to show all vaccinations in all groups, you can loop over the nested snapshots in your onDataChange:
databaseReference = FirebaseDatabase.getInstance().getReference("groupVaccinations");
groupVaccinations = new ArrayList<>();
AllGroupVaccinationList groupVaccinationInfoAdapter = new AllGroupVaccinationList(ActivityAllGroupVaccinations.this, groupVaccinations);
listView.setAdapter(groupVaccinationInfoAdapter);
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot groupVaccinationSnapshot : dataSnapshot.getChildren()){
for(DataSnapshot vaccinationSnapshot : groupVaccinationSnapshot.getChildren()){
GroupVaccination groupVaccination = vaccinationSnapshot.getValue(GroupVaccination.class);
groupVaccinations.add(groupVaccination);
}
}
groupVaccinationInfoAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore errors
}
});
I also changed the code to call groupVaccinationInfoAdapter.notifyDataSetChanged(), so that you can keep using the same adapter and update it if needed.
You will need to go one level deeper where your id -LZk5tpB5PXqHVJkj8Vz (GroupID) contains all the sub pushKeys (groupVaccinationID) with data inside.
listView = (ListView)findViewById(R.id.listItemAllGroupVaccinations);
databaseReference = FirebaseDatabase.getInstance().getReference("groupVaccinations").child("-LZk5tpB5PXqHVJkj8Vz");
groupVaccinations = new ArrayList<>();
protected void onStart(){
super.onStart();
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot groupVaccinationSnapshot : dataSnapshot.getChildren()){
GroupVaccination groupVaccination = groupVaccinationSnapshot.getValue(GroupVaccination.class);
groupVaccinations.add(groupVaccination);
}
AllGroupVaccinationList groupVaccinationInfoAdapter = new AllGroupVaccinationList(ActivityAllGroupVaccinations.this, groupVaccinations);
listView.setAdapter(groupVaccinationInfoAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
EDIT
The -LZk5tpB5PXqHVJkj8Vz child should be avoided since is hardcoded to show you this example, instead, you should take that child key from where you get your GroupID, doing that you can get as Frank says all the vaccinations from each GroupID.
I'm facin a really weird problem, Im calling two nodes in my database , from one node I get all my user ids , then I just loop inside my user node to get the user metadata. The problem is that when I run the debugger, it seems like the mAdapter is beign called before the data is beign fetched. So my adapter set the recyclerview with no data. After the adapter has been called, my query fetching the user begins and the array is populated normally
This is what I have done so far
mDatabase.child("teamsNode").child(teamID).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot snapshot : dataSnapshot.getChildren()){
mDatabase.child("users").child(snapshot.getKey()).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
UserModel model = dataSnapshot.getValue(UserModel.class);
String playerName = model.getName();
model.setName(playerName);
mArrayPlayers.add(model);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) { }
});
}
mAdapter = new PlayersAdapter(mArrayPlayers,mContext,R.layout.recycler_row);
if(mAdapter.getItemCount()>0)
mRecyclerView.setAdapter(mAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) { }
});
As you can see, I set the adapter to the recyclerview after the first foreach that fetchs all the data, I know that beign asynchronous I need to wait for the inner mDatabase to be done but if I move the setting of the adapter one line above to wait for the second call to finish it does the same, any idea?
Database structure is like this
teamsNode
|__Jm2KSMjslpow2Ipoasz : true
|__601KSMjsldfjd2Ipos0 : true
|__asgm2Kshalpow2IposJ : true
users
|__Jm2KSMjslpow2Ipoasz
|_____name: randomname1
|__601KSMjsldfjd2Ipos0
|_____name: randomname2
|__asgm2Kshalpow2IposJ
|_____name: randomname3
Recyclerview is not populated. Any idea?
A weird thing is that sometimes runing it with the debugger does fill the data, but its rarely to happend.
If you want to only initialize the adapter when all data is loaded, you will need to do so in the nested onDataChange callback:
mDatabase.child("teamsNode").child(teamID).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshotTeam) {
AtomicInteger loadedUserCount = new AtomicInteger(0);
for(DataSnapshot snapshot : dataSnapshotTeam.getChildren()){
mDatabase.child("users").child(snapshot.getKey()).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
UserModel model = dataSnapshot.getValue(UserModel.class);
String playerName = model.getName();
model.setName(playerName);
mArrayPlayers.add(model);
if (loadedUserCount.getAndIncrement() + 1 == dataSnapshotTeam.getChildrenCount()) {
mAdapter = new PlayersAdapter(mArrayPlayers,mContext,R.layout.recycler_row);
if(mAdapter.getItemCount()>0) {
mRecyclerView.setAdapter(mAdapter);
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore errors
}
});
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
throw databaseError.toException(); // don't ignore errors
}
});
The problem you have is that the calls to the addListenerForSingleValueEvent methods are asynchronous, so they are executed in another thread. When you call the second addListenerForSingleValueEvent this is executed in another thread, while the main thread follows its execution. You have to do the call of your adapter in the answer of your second call addListenerForSingleValueEvent in the onDataChange method. In this way to avoid anomalous operations of your application.
Hope this will help.
mDatabase.child("teamsNode").child(teamID).addListenerForSingleValueEvent(new ValueEventListener() {
mArrayPalyer.clear();//add this
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot snapshot : dataSnapshot.getChildren()){
mDatabase.child("users").child(snapshot.getKey()).addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
UserModel model = dataSnapshot.getValue(UserModel.class);
String playerName = model.getName();
model.setName(playerName);
mArrayPlayers.add(model);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
}
mAdapter = new PlayersAdapter(mArrayPlayers,mContext,R.layout.recycler_row);
mRecyclerView.setAdapter(mAdapter); //makes changes here because you are checking for adapter item count before setting it and this always return null.
}
You can look at my code I am using ValueEventListener just like you and binding the data to recycler view
ValueEventListener postListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()){
UserListModel userListModel =dataSnapshot1.getValue(UserListModel.class);
userModelArrayList.add(userListModel);
}
userListAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.w(">>value", "loadPost:onCancelled", databaseError.toException());
}
};
//mDatabase is the reference to the Firebase Node
mDatabase.addValueEventListener(postListener);
userListRecyclerView.setLayoutManager(M.gridLayoutRecyclerView(getActivity() , 2));
userListAdapter = new UserListAdapter(getActivity(), userModelArrayList);
userListRecyclerView.setAdapter(userListAdapter);
This is the structure of my database:
I want to get all the outcome value, but I need to loop the faculty child first and the exam child before I able to use the getValue() in outcome. How can I loop the faculty child and exam child in the same time?
This is my code, but I don't know how to get to the Exam child and loop it again to get the outcome value.
dbOutcome.child("sample_list").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for(DataSnapshot ds: dataSnapshot.getChildren()){
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
You can use the models classes to retrieve this.
Make model classes and get data in them
public class Exam {
pirvate String outcomes;
// create constructor and getter setter
}
create Faculty class
public class Faculty {
List<Exam> exams
// create constructor and getter setter
}
get Data from snapshot in onDataChange like this
public void onDataChange(DataSnapshot dataSnapshot) {
List<Faculty> faculties = (ArrayList<Faculty>) dataSnapshot.getValue();
}
I want to get all the outcome value
Assuming that the sample_list node is a direct child of your Firebase root, to solve this, you need use getChildren() method twice:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference ref = rootRef.child("sample_list");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot dSnapshot : dataSnapshot.getChildren()) {
for(DataSnapshot ds : dSnapshot.getChildren()) {
String outcome = ds.child("outcome").getValue(String.class);
Log.d("TAG", outcome);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
ref.addListenerForSingleValueEvent(valueEventListener);
The output in your logcat will be:
pass
fail
pass
fail