I have list of node's ids and i want to retrive all child of that node.
This is my data
where each id is a recipe id :
This my code to retrive the ids then i save it in an arrylist :
data_ref_user = FirebaseDatabase.getInstance().getReference("Users").child(current_uid).child("My Recipes");
data_ref_user.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists()){
for (DataSnapshot dataSnapshot:snapshot.getChildren()){
String recipe_id = dataSnapshot.getValue().toString();
list_recipes_id.add(recipe_id);
}//end for
}else {
Toast.makeText(getContext(), "No data found!", Toast.LENGTH_LONG).show();
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException();
}
});
And then i try to loop throught list_recipe_id adding a valueEventListener and saving the recipe into recipe_list .
data_ref_recipe = FirebaseDatabase.getInstance().getReference("Recipes");
data_ref_recipe.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for(DataSnapshot data:snapshot.getChildren()) {
for (String ids :list_recipes_id){
Recipe recipe = data.child(ids).getValue(Recipe.class);
recipe_list.add(0,recipe);
}//end inner loop
Recipe recipe = data.getValue(Recipe.class);
recipe_list.add(0,recipe); //0 to put data in first not buttom
}
newAdapter.notifyDataSetChanged();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException();
}
});
i hope i can find a way to retrive the data of all saved id?
Related
How to read data from two different firebase database parent node in a recyclerview.
I want to fetch data from two different firebase parent node recyclerview, but i ended up reading only one node from firebase and displying to recycyclerview.
// Load data from Firebase into mDataList
private void loadDataFromFirebase() {
mDataList.clear();
mDatabase.child("QnA").child("Questions").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
scholarid = childSnapshot.child("id").getValue(String.class);
// System.out.println(id);
question_profile_read_data dataModel = childSnapshot.getValue(question_profile_read_data.class);
mDataList.add(dataModel);
notifyDataSetChanged();
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.w(TAG, "loadPost:onCancelled", databaseError.toException());
}
});
System.out.println(scholarid);
mDatabase.child("users").child("child").child("profiles").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
// for (DataSnapshot childSnapshot : dataSnapshot.getChildren()) {
question_profile_read_data dataModel = dataSnapshot.getValue(question_profile_read_data.class);
mDataList.add(dataModel);
notifyDataSetChanged();
System.out.println(scholarid);
// }
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.w(TAG, "loadPost:onCancelled", databaseError.toException());
}
});
}
I used above method to retrieve data and i used this method in adapter class. but this only reading data from single database.
I already done one by one add value to realtime database from the dropdown with add button.
here my code for adding a single value
private void SaveStudent() {
Query query = databaseReference.orderByChild("lrn").equalTo(StudentLRN);
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists()) {
databaseReference = firebaseDatabase.getReference("Class");
Query query = databaseReference.child(className).child("StudentLRN")
.child(StudentLRN);
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.exists()) {
autoCompleteSelectStudent.setText("");
autoCompleteSelectSection.setText("");
textInputLayoutStudent.setVisibility(View.GONE);
Toast.makeText(TeacherClassroomActivity.this, StudentName + " Already Added!", Toast.LENGTH_SHORT).show();
} else {
databaseReference = firebaseDatabase.getReference("Class");
databaseReference.child(className)
.child("StudentLRN").child(StudentLRN)
.child("LRN").setValue(StudentLRN);
databaseReference.child(className)
.child("StudentLRN").child(StudentLRN)
.child("StudentName").setValue(StudentName);
autoCompleteSelectStudent.setText("");
autoCompleteSelectSection.setText("");
Toast.makeText(TeacherClassroomActivity.this, StudentName + " Added Successfully!", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
};
query.addListenerForSingleValueEvent(eventListener);
} else {
Toast.makeText(TeacherClassroomActivity.this, "No Student Exist in this LRN!!", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
};
query.addListenerForSingleValueEvent(eventListener);
}
Student list
and from the image above i want to add all student from dropdown list in one submit button.
Example Data Model:
I am trying to get the position of the child so that every time I click the items, I can edit the data. I am using a Recycler Adapter by the way.
How can I get to the end of a specific child which has different edited key?
mDatabaseReferenceAttendance = FirebaseDatabase.getInstance().getReference("Attendance").child("Record");
mDatabaseReferenceAttendance.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if(snapshot.exists()){
for(DataSnapshot dataSnapshot : snapshot.getChildren()){
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
Your code reads all data under Attendance/Record. If you want to show the data for John-Smith on April 10, 2022-test (and similar nodes), you can loop over the extra levels in your JSON with:
mDatabaseReferenceAttendance = FirebaseDatabase.getInstance().getReference("Attendance").child("Record");
mDatabaseReferenceAttendance.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for(DataSnapshot dateSnapshot : snapshot.getChildren()){
for(DataSnapshot userSnapshot : dateSnapshot.getChildren()){
System.out.println(userSnapshot.getKey()); // "John-Smith"
System.out.println(userSnapshot.child("description").getValue(String.class)); // "test"
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException(); // never ignore errors
}
});
I have a Firebase database with a "users" node that has some children and I would like to retrieve the "type" field for a specific user, but I don't know what that user's key would be. I have the following data structure:
users
-MlHrU3_UgMzrU3IpfOW
email:
"mail#gmail.com"
tipo:
"Aluno"
I tried to do it like this but it always returns null
final String[] tipoUserBD = new String[1];
database = FirebaseDatabase.getInstance().getReference("users");
database.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
list.clear();
for(DataSnapshot dataSnapshot : snapshot.getChildren()){
if(dataSnapshot.child("email").getValue(String.class).equals(user.getEmail())) {
tipoUser[0] = dataSnapshot.child("tipo").getValue().toString();
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
If you know the key of the user (I know you don't, but let's assume you do in some other case), you can read their profile and log their type with:
database = FirebaseDatabase.getInstance().getReference("users");
database.child("-MlHrU3_UgMzrU3IpfOW").addValueEventListener(new ValueEventListener() {
// 👆 use the key here
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
Log.d("Tipo", dataSnapshot.child("tipo").getValue(String.class)); // 👈 Specify type here
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException(); // 👈 never ignore errors
}
});
If you know some property that identifies the user, but not the key, you can use a query to find the matching nodes:
database = FirebaseDatabase.getInstance().getReference("users");
database.orderByChild("email").equalTo("mail#gmail.com").addValueEventListener(new ValueEventListener() {
// 👆 use the property name and value here
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for(DataSnapshot dataSnapshot : snapshot.getChildren()){
Log.d("Tipo", dataSnapshot.child("tipo").getValue(String.class)); // 👈 Specify type here
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException(); // 👈 never ignore errors
}
});
If you don't know anything about the user, the best you can do is loop over all of them:
database = FirebaseDatabase.getInstance().getReference("users");
database.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for(DataSnapshot dataSnapshot : snapshot.getChildren()){
Log.d("Tipo", dataSnapshot.child("tipo").getValue(String.class));
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
throw error.toException(); // 👈 never ignore errors
}
});
The trick you're trying to do with tipoUser[0] is an anti-pattern, as it typically means you're ignoring that data is loaded asynchronously.
As a general (and hard) rules: any code that needs the data from the database will need to be inside onDataChange or be called from there.
For more on this, and examples, see:
getContactsFromFirebase() method return an empty list
Setting Singleton property value in Firebase Listener
ccontacts = new ArrayList<>();
DatabaseReference dbGelenler = db.getReference("Filmler");
dbGelenler.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot gelenler:dataSnapshot.getChildren()){
ccontacts.add(new Data(gelenler.getValue(Film.class).getAciklama(),gelenler.getValue(Film.class).getBen(),gelenler.getValue(Film.class).getImdb(),gelenler.getValue(Film.class).getIsim(),gelenler.getValue(Film.class).getIzlemeLinki(),gelenler.getValue(Film.class).getKategori(),gelenler.getValue(Film.class).getNe(),gelenler.getValue(Film.class).getService(),gelenler.getValue(Film.class).getTrailer(),gelenler.getValue(Film.class).getUrl(),gelenler.getValue(Film.class).getWhat(),gelenler.getValue(Film.class).getYear()));
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
for (Data d:ccontacts){
b.setText(d.getIsim());
}
When I directly set the text via gelenler.getValue() it works, however when I want to populate an ArrayList with this information it fails and receives null. Any help would be appreciated.