I have the following structure
root
-class1
-section1
-student1
-firstname
-lastname
-student2
-firstname
-lastname
-section2
-student1
-firstname
-lastname
-student2
-firstname
-lastname
I need to get the section number (Section1, section2...) and for every section, the lastname for student2.
The problem that i facing is that it is all in a Fragment class in android that I need to display and nothing seems to be working. I have referred this for getting the children too, but the for loop somehow does not work and I get Null values on retrieval.
I need to get
section1, lastname (of student2 in section1)
section2, lastname (of student2 in section2)
...
and so on until all sections are exhausted
U can make a model class like
class Class{
Arrylist<section> sections;
};
class section{
Arrylist<Student> students;
};
class Student{
String firstname, lastname;
};
then get the value of classes
have other way, without making many model classes, but that is more painful and time consuming . If u want that feel free to comment.
Please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference classRef = rootRef.child("class1");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String lastname = ds.child("student2").child("lastname").getValue(String.class);
Log.d("TAG", lastname);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
classRef.addListenerForSingleValueEvent(eventListener);
Related
I want to clone/Duplicate a linear_layout, through java from Firebase reatime-database.
I the screenshot I have a child history which contains user_id's and it's childs and so on. I want to put it dynamically in this layout.
I have statically copied the layout three times, but I want to make it dynamic, same as the size of the history table entries with current user id.
Also I do have a class User with getter setter and constructor.
To get the user ids under the history node and use them to add a User object to the database, please use the following code:
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference uidRef = rootRef.child("history").child(uid);
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String key = ds.getKey();
DatabaseReference keyRef = rootRef.child("users").child(key);
User user = new User(/* ... */); //Pass data to the constructor
keyRef.setValue(user);
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
Log.d(TAG, databaseError.getMessage());
}
};
uidRef.addListenerForSingleValueEvent(valueEventListener);
I already have knowledge in retrieving data from firebase. The thing is, the data i want to retrieve lies under 3 parent nodes, and I can't figure any way how to retrieve data from the database 3 nodes deep. What I want is to get all the values of the key named "name" and display it in a listview.
To display all those names, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference medicinesRef = rootRef.child("Medicines");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String name = ds.child("name").getValue(String.class);
Log.d("TAG", name);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
medicinesRef.addListenerForSingleValueEvent(eventListener);
Your output will be:
amoxcillin
paracetamol
mefenamic
In my DB each user has friends. And I need to get 50 last posts of the user's friends. See below structure of posts of each user in Firebase DB.
So what is optimal way to do that? If a user has for example 150 friends, then my Android app should have as many listeners as friends. Is it ok to have 150 or more DB listeners in the app? Also what is the way to get all friends' posts in single query? Thanks.
root
- posts
- {userUid}
- {postUid}
- text
- dateCreated
You can have as many listeners as you want with the condition to remove them according to your life-cycle of your activity. But in your case, you don't need 150 listeners, you only need just one. Assuming that the node under the user is is named friends, you can attach a single listener on friends node and then iterate over the DataSnapshot object using getChildren() method. Assuming that your database looks simmilar with this:
Firebase-root
|
--- users
|
--- uid1
|
--- friends
|
--- friendId1: true
|
--- friendId2: true
To get all the friends that corespond to a particular user, please use the following code:
String uid = firebaseAuth.getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference friendsRef = rootRef.child("users").child(uid).child(friends);
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String friendId = ds.getKey();
Log.d("TAG", friendId);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
friendsRef.addListenerForSingleValueEvent(eventListener);
To get all post that of all users, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference postsRef = rootRef.child("posts");
ValueEventListener valueEventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String uid = ds.getKey();
DatabaseReference uidRef = postsRef.child(uid);
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot dSnapshot : dataSnapshot.getChildren()) {
String text = dSnapshot.child("text").getValue(String.class);
long dateCreated = dSnapshot.child("dateCreated").getValue(Long.class);
Log.d("TAG", text + " / " + dateCreated)
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
uidRef.addListenerForSingleValueEvent(eventListener);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
postsRef.addListenerForSingleValueEvent(valueEventListener);
What I would do is have a friendsListener, once initialized I would loop through my friends and register their reference in my listener vs 150 listeners.
You can have 150+ listeners but the less the better. Maybe you can just watch all posts instead of listening to every friend separtely.
To get all posts of a friend once try:
ref('posts').child(friendUid).once('value').then(function(snapshot) {
console.log(snapshot.val());
});
To get the last 50 posts of a friend once try:
ref('posts').child(friendUid).orderByChild("dateCreated").limitToLast(50).once('value').then(function(snapshot) {
console.log(snapshot.val());
});
(depending on your dateCreated property you might need to use limitToFirst instead of limitToLast. Check the Firebase Query docu for more information.)
I'm starting to code Android Apps with the database connection. As IDE I use Android Studio and Firebase for the database. This is my data structure in Firebase:
In my app, I need to fill a ListView with all the names. So I want the data from three children from the child "Rezepte" from the UUID child. I hope this is understandable.
I've done a lot of googling and I just can't figure out how this works. My current version of the java code is this:
final FirebaseUser user = firebaseAuth.getCurrentUser();
// trying to get the reference of the right path
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child(user.getUid()).child("Rezepte");
ref.addListenerForSingleValueEvent(
new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
// calling a method which should read the data from the snapshot and put it into the ListView
fillList((Map<String, Object>) dataSnapshot.child(user.getUid()).child("Rezepte").getValue());
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(RezepteActivity.this, "Daten konnten nicht gelesen werden", Toast.LENGTH_SHORT).show();
}
});
}
private void fillList(Map<String, Object> entries) {
// loop to cycle through every child of "Rezepte" and get the names
for (Map.Entry<String, Object> entry : entries.entrySet()) {
Map singleEntry = (Map) entry.getValue();
// add the name to an ArrayList of all names
Rezepte.add((String) singleEntry.get("name"));
}
// put the data into the ListView
lvRezepte.addFooterView(lvRezepte, Rezepte, true);
}
The app always crashes and I don't really understand a lot in the debugger. But the error occurs already in the onDataChange void.
I would be really happy if someone could help me.
You're trying to traverse down the hierarchy in your result DataSnapshot when you've already done so in your query itself. So in your onDataChange() you need to just put:
fillList(datasnapshot.getValue()) //Map of results at /{uid}/Rezepte
Assuming that fillList method works properly, you should first fix the following line
fillList((Map<String, Object>) dataSnapshot.child(user.getUid()).child("Rezepte").getValue())
to
fillList((Map<String, Object>) dataSnapshot.getValue())
You already have a reference to Rezepte child of the current user when you declared it like this:
DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child(user.getUid()).child("Rezepte")
Your snapshot has 1, 2, and 3 as children, so you shouldn't reinforce the path you declared in the reference.
To get all those names and add them to an ArrayList, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference rezepeteRef = rootRef.child(user.getUid()).child("Rezepte");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
List<String> list = new ArrayList<>();
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String name = ds.child("name").getValue(String.class);
list.add(name);
Log.d("TAG", name);
}
Log.d("TAG", list);
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
rezepeteRef.addListenerForSingleValueEvent(eventListener);
I have this in the database:
When a teacher adds a Class and a Section a random id is generated using push() under node Class.
There is also a Student and a Teacher node with ids and attributes.
The student joins a class, thus also creating a random id in ClassStudent with the above attribute.
In node Student the id is the current userid and under it there is attribute. Now my question is, is it a good way to retrieve the name from the Student node and add it to the ClassStudent node?
Im using this code:
DatabaseReference gets=FirebaseDatabase.getInstance().getReference().child("Student");
final DatabaseReference getid=FirebaseDatabase.getInstance().getReference().child("Class");
ValueEventListener valueEventListener1= new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot child: dataSnapshot.getChildren()) {
String classnames = child.child("Classname").getValue().toString();
if (returnString.equals(classnames)) {
String getids = child.getKey();
newtable.child("ClassId").setValue(getids);
}
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
};
getid.addValueEventListener(valueEventListener1);
The reason I have a name because later on I want to click on a class and get the list of names in that class. So if i add the Student id(which is done already) in node ClassStudent, how will I be able to on click retrieve the name of the Students without having studentname in ClassStudent?
Edit:
If I query on ClassStudent , I want to retrieve the class names in one activity then on another activity, I want to retrieve the Students names of a class. I dont want Studentname to be inside ClassStudent since logically I think it seems incorrect.
Example:
1. Student registers himself in a class (a random id with attribute classid and studentid is created).
Then I want to retrieve the classnames in onResume(), so after login the classes are there in activity(like a join between ClassStudent and Class`)
On completely different activity, I want to retrieve the studentnames in a list while also querying on ClassStudent (like a join between ClassStudent and Student)
Output of # 3. after querying:
Peter Haddad
John
Phillip
//names
To get all the stundet names under the ClassStudent node, please use the following code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference classStudentRef = rootRef.child("ClassStudent");
ValueEventListener eventListener = new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren()) {
String Studentname = ds.child("Studentname").getValue(String.class);
Log.d("TAG", Studentname);
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
};
classStudentRef.addListenerForSingleValueEvent(eventListener);
Your out out will be:
Peter Haddad
//other names